Add a function to determine if a window is the focus widget within its
authorOwen Taylor <otaylor@redhat.com>
Mon, 11 Dec 2000 17:47:24 +0000 (17:47 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Mon, 11 Dec 2000 17:47:24 +0000 (17:47 +0000)
Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>

* gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
to determine if a window is the focus widget within
its toplevel.

* gtk/gtkcontainer.[ch]: Fix the return type of ::focus
to be boolean.

* gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
of the case where the container CAN_FOCUS to here instead
of having it in each individual move-the-focus place.

* gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
focusing to be geometric in a much more obvious sense. Arrowing
around is still non-intuitive because it isn't perfect and
because entries, etc, grab the arrow keys, but it at least
usually will do what you expect now.

* gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
file.

* gtk/gtknotebook.c: Change tabs to be a single item in
the focus chain. Make movement of focus on tabs with arrow
keys wrap around.

* gtk/gtknotebook.c (gtk_notebook_find_child): Add
CHECK_FIND_CHILD macro to give informative error messages
instead of silent returns.

* gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
flag since we handle GdkReturn on the tabs.

* gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
windows rather than sending expose events directly.

* gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
definition for GtkNotebookPage into .c file, since it is private.

* gtk/testgtk.c (create_notebook): Add option for
testing borderless notebook.

* gtk/testgtk.c (page_switch): Removed egregious poking
around in GTK+ internals.

* docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.

* gtk/gtkclist.[ch]: Remove key press handler, handle focusing
properly through gtk_clist_focus. Make the title headers a
single item in the tab-focus chain, and make left-right wrap
around.

* gtk/gtkwindow.c (gtk_window_focus): Add a custom
focus method so that wrapping around works properly.

* gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
that is handled for the widget now.

23 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/Changes-2.0.txt
docs/reference/ChangeLog
docs/reference/gtk/tmpl/gtknotebook.sgml
docs/widget_system.txt
gtk/gtkclist.c
gtk/gtkclist.h
gtk/gtkcontainer.c
gtk/gtkcontainer.h
gtk/gtknotebook.c
gtk/gtknotebook.h
gtk/gtktreeview.c
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwindow.c
gtk/testgtk.c
tests/testgtk.c

index d951aa6465ca780dcf68a6ead98bfa9013942698..b43810e86698cc4c55de55517beb666f29ff151c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>
+       
+       * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+       to determine if a window is the focus widget within
+       its toplevel.
+
+       * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+       to be boolean.
+
+       * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling 
+       of the case where the container CAN_FOCUS to here instead
+       of having it in each individual move-the-focus place.
+
+       * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+       focusing to be geometric in a much more obvious sense. Arrowing
+       around is still non-intuitive because it isn't perfect and
+       because entries, etc, grab the arrow keys, but it at least
+       usually will do what you expect now.
+       
+       * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+       file.
+
+       * gtk/gtknotebook.c: Change tabs to be a single item in
+       the focus chain. Make movement of focus on tabs with arrow
+       keys wrap around.
+       
+       * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+       CHECK_FIND_CHILD macro to give informative error messages
+       instead of silent returns.
+
+       * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT 
+       flag since we handle GdkReturn on the tabs.
+
+       * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+       windows rather than sending expose events directly.
+
+       * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure 
+       definition for GtkNotebookPage into .c file, since it is private.
+
+       * gtk/testgtk.c (create_notebook): Add option for 
+       testing borderless notebook.
+
+       * gtk/testgtk.c (page_switch): Removed egregious poking
+       around in GTK+ internals.
+
+       * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+       * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+       properly through gtk_clist_focus. Make the title headers a
+       single item in the tab-focus chain, and make left-right wrap
+       around.
+
+       * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+       focus method so that wrapping around works properly.
+
+       * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - 
+       that is handled for the widget now. 
+
 Mon Dec 11 11:41:12 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000  Owen Taylor  <otaylor@redhat.com>
 2000-12-06  Elliot Lee  <sopwith@redhat.com>
 
        * configure.in: Detect freetype properly
+
        * modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
        above.
 
index d951aa6465ca780dcf68a6ead98bfa9013942698..b43810e86698cc4c55de55517beb666f29ff151c 100644 (file)
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>
+       
+       * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+       to determine if a window is the focus widget within
+       its toplevel.
+
+       * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+       to be boolean.
+
+       * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling 
+       of the case where the container CAN_FOCUS to here instead
+       of having it in each individual move-the-focus place.
+
+       * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+       focusing to be geometric in a much more obvious sense. Arrowing
+       around is still non-intuitive because it isn't perfect and
+       because entries, etc, grab the arrow keys, but it at least
+       usually will do what you expect now.
+       
+       * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+       file.
+
+       * gtk/gtknotebook.c: Change tabs to be a single item in
+       the focus chain. Make movement of focus on tabs with arrow
+       keys wrap around.
+       
+       * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+       CHECK_FIND_CHILD macro to give informative error messages
+       instead of silent returns.
+
+       * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT 
+       flag since we handle GdkReturn on the tabs.
+
+       * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+       windows rather than sending expose events directly.
+
+       * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure 
+       definition for GtkNotebookPage into .c file, since it is private.
+
+       * gtk/testgtk.c (create_notebook): Add option for 
+       testing borderless notebook.
+
+       * gtk/testgtk.c (page_switch): Removed egregious poking
+       around in GTK+ internals.
+
+       * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+       * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+       properly through gtk_clist_focus. Make the title headers a
+       single item in the tab-focus chain, and make left-right wrap
+       around.
+
+       * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+       focus method so that wrapping around works properly.
+
+       * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - 
+       that is handled for the widget now. 
+
 Mon Dec 11 11:41:12 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000  Owen Taylor  <otaylor@redhat.com>
 2000-12-06  Elliot Lee  <sopwith@redhat.com>
 
        * configure.in: Detect freetype properly
+
        * modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
        above.
 
index d951aa6465ca780dcf68a6ead98bfa9013942698..b43810e86698cc4c55de55517beb666f29ff151c 100644 (file)
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>
+       
+       * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+       to determine if a window is the focus widget within
+       its toplevel.
+
+       * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+       to be boolean.
+
+       * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling 
+       of the case where the container CAN_FOCUS to here instead
+       of having it in each individual move-the-focus place.
+
+       * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+       focusing to be geometric in a much more obvious sense. Arrowing
+       around is still non-intuitive because it isn't perfect and
+       because entries, etc, grab the arrow keys, but it at least
+       usually will do what you expect now.
+       
+       * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+       file.
+
+       * gtk/gtknotebook.c: Change tabs to be a single item in
+       the focus chain. Make movement of focus on tabs with arrow
+       keys wrap around.
+       
+       * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+       CHECK_FIND_CHILD macro to give informative error messages
+       instead of silent returns.
+
+       * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT 
+       flag since we handle GdkReturn on the tabs.
+
+       * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+       windows rather than sending expose events directly.
+
+       * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure 
+       definition for GtkNotebookPage into .c file, since it is private.
+
+       * gtk/testgtk.c (create_notebook): Add option for 
+       testing borderless notebook.
+
+       * gtk/testgtk.c (page_switch): Removed egregious poking
+       around in GTK+ internals.
+
+       * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+       * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+       properly through gtk_clist_focus. Make the title headers a
+       single item in the tab-focus chain, and make left-right wrap
+       around.
+
+       * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+       focus method so that wrapping around works properly.
+
+       * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - 
+       that is handled for the widget now. 
+
 Mon Dec 11 11:41:12 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000  Owen Taylor  <otaylor@redhat.com>
 2000-12-06  Elliot Lee  <sopwith@redhat.com>
 
        * configure.in: Detect freetype properly
+
        * modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
        above.
 
index d951aa6465ca780dcf68a6ead98bfa9013942698..b43810e86698cc4c55de55517beb666f29ff151c 100644 (file)
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>
+       
+       * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+       to determine if a window is the focus widget within
+       its toplevel.
+
+       * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+       to be boolean.
+
+       * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling 
+       of the case where the container CAN_FOCUS to here instead
+       of having it in each individual move-the-focus place.
+
+       * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+       focusing to be geometric in a much more obvious sense. Arrowing
+       around is still non-intuitive because it isn't perfect and
+       because entries, etc, grab the arrow keys, but it at least
+       usually will do what you expect now.
+       
+       * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+       file.
+
+       * gtk/gtknotebook.c: Change tabs to be a single item in
+       the focus chain. Make movement of focus on tabs with arrow
+       keys wrap around.
+       
+       * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+       CHECK_FIND_CHILD macro to give informative error messages
+       instead of silent returns.
+
+       * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT 
+       flag since we handle GdkReturn on the tabs.
+
+       * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+       windows rather than sending expose events directly.
+
+       * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure 
+       definition for GtkNotebookPage into .c file, since it is private.
+
+       * gtk/testgtk.c (create_notebook): Add option for 
+       testing borderless notebook.
+
+       * gtk/testgtk.c (page_switch): Removed egregious poking
+       around in GTK+ internals.
+
+       * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+       * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+       properly through gtk_clist_focus. Make the title headers a
+       single item in the tab-focus chain, and make left-right wrap
+       around.
+
+       * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+       focus method so that wrapping around works properly.
+
+       * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - 
+       that is handled for the widget now. 
+
 Mon Dec 11 11:41:12 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000  Owen Taylor  <otaylor@redhat.com>
 2000-12-06  Elliot Lee  <sopwith@redhat.com>
 
        * configure.in: Detect freetype properly
+
        * modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
        above.
 
index d951aa6465ca780dcf68a6ead98bfa9013942698..b43810e86698cc4c55de55517beb666f29ff151c 100644 (file)
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>
+       
+       * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+       to determine if a window is the focus widget within
+       its toplevel.
+
+       * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+       to be boolean.
+
+       * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling 
+       of the case where the container CAN_FOCUS to here instead
+       of having it in each individual move-the-focus place.
+
+       * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+       focusing to be geometric in a much more obvious sense. Arrowing
+       around is still non-intuitive because it isn't perfect and
+       because entries, etc, grab the arrow keys, but it at least
+       usually will do what you expect now.
+       
+       * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+       file.
+
+       * gtk/gtknotebook.c: Change tabs to be a single item in
+       the focus chain. Make movement of focus on tabs with arrow
+       keys wrap around.
+       
+       * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+       CHECK_FIND_CHILD macro to give informative error messages
+       instead of silent returns.
+
+       * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT 
+       flag since we handle GdkReturn on the tabs.
+
+       * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+       windows rather than sending expose events directly.
+
+       * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure 
+       definition for GtkNotebookPage into .c file, since it is private.
+
+       * gtk/testgtk.c (create_notebook): Add option for 
+       testing borderless notebook.
+
+       * gtk/testgtk.c (page_switch): Removed egregious poking
+       around in GTK+ internals.
+
+       * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+       * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+       properly through gtk_clist_focus. Make the title headers a
+       single item in the tab-focus chain, and make left-right wrap
+       around.
+
+       * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+       focus method so that wrapping around works properly.
+
+       * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - 
+       that is handled for the widget now. 
+
 Mon Dec 11 11:41:12 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000  Owen Taylor  <otaylor@redhat.com>
 2000-12-06  Elliot Lee  <sopwith@redhat.com>
 
        * configure.in: Detect freetype properly
+
        * modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
        above.
 
index d951aa6465ca780dcf68a6ead98bfa9013942698..b43810e86698cc4c55de55517beb666f29ff151c 100644 (file)
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>
+       
+       * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+       to determine if a window is the focus widget within
+       its toplevel.
+
+       * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+       to be boolean.
+
+       * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling 
+       of the case where the container CAN_FOCUS to here instead
+       of having it in each individual move-the-focus place.
+
+       * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+       focusing to be geometric in a much more obvious sense. Arrowing
+       around is still non-intuitive because it isn't perfect and
+       because entries, etc, grab the arrow keys, but it at least
+       usually will do what you expect now.
+       
+       * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+       file.
+
+       * gtk/gtknotebook.c: Change tabs to be a single item in
+       the focus chain. Make movement of focus on tabs with arrow
+       keys wrap around.
+       
+       * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+       CHECK_FIND_CHILD macro to give informative error messages
+       instead of silent returns.
+
+       * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT 
+       flag since we handle GdkReturn on the tabs.
+
+       * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+       windows rather than sending expose events directly.
+
+       * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure 
+       definition for GtkNotebookPage into .c file, since it is private.
+
+       * gtk/testgtk.c (create_notebook): Add option for 
+       testing borderless notebook.
+
+       * gtk/testgtk.c (page_switch): Removed egregious poking
+       around in GTK+ internals.
+
+       * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+       * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+       properly through gtk_clist_focus. Make the title headers a
+       single item in the tab-focus chain, and make left-right wrap
+       around.
+
+       * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+       focus method so that wrapping around works properly.
+
+       * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - 
+       that is handled for the widget now. 
+
 Mon Dec 11 11:41:12 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000  Owen Taylor  <otaylor@redhat.com>
 2000-12-06  Elliot Lee  <sopwith@redhat.com>
 
        * configure.in: Detect freetype properly
+
        * modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
        above.
 
index d951aa6465ca780dcf68a6ead98bfa9013942698..b43810e86698cc4c55de55517beb666f29ff151c 100644 (file)
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000  Owen Taylor  <otaylor@redhat.com>
+       
+       * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+       to determine if a window is the focus widget within
+       its toplevel.
+
+       * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+       to be boolean.
+
+       * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling 
+       of the case where the container CAN_FOCUS to here instead
+       of having it in each individual move-the-focus place.
+
+       * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+       focusing to be geometric in a much more obvious sense. Arrowing
+       around is still non-intuitive because it isn't perfect and
+       because entries, etc, grab the arrow keys, but it at least
+       usually will do what you expect now.
+       
+       * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+       file.
+
+       * gtk/gtknotebook.c: Change tabs to be a single item in
+       the focus chain. Make movement of focus on tabs with arrow
+       keys wrap around.
+       
+       * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+       CHECK_FIND_CHILD macro to give informative error messages
+       instead of silent returns.
+
+       * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT 
+       flag since we handle GdkReturn on the tabs.
+
+       * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+       windows rather than sending expose events directly.
+
+       * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure 
+       definition for GtkNotebookPage into .c file, since it is private.
+
+       * gtk/testgtk.c (create_notebook): Add option for 
+       testing borderless notebook.
+
+       * gtk/testgtk.c (page_switch): Removed egregious poking
+       around in GTK+ internals.
+
+       * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+       * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+       properly through gtk_clist_focus. Make the title headers a
+       single item in the tab-focus chain, and make left-right wrap
+       around.
+
+       * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+       focus method so that wrapping around works properly.
+
+       * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - 
+       that is handled for the widget now. 
+
 Mon Dec 11 11:41:12 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000  Owen Taylor  <otaylor@redhat.com>
 2000-12-06  Elliot Lee  <sopwith@redhat.com>
 
        * configure.in: Detect freetype properly
+
        * modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
        above.
 
index 50877024bcccbb68e8b4a3026b61badac96d4938..0c5789f39d381f27bca32df6618dac7ae307ec68 100644 (file)
@@ -255,6 +255,10 @@ Incompatible Changes from GTK+-1.2 to GTK+-2.0:
   void       gtk_progress_bar_set_orientation      (GtkProgressBar *pbar,
                                                    GtkProgressBarOrientation orientation);
 
+* The GtkNotebookPage structure has been removed from the public header files;
+  this was never meant to be a public structure, and all functionality that
+  could be done by accessing the struct fields of this structure should be 
+  accesible otherwise.
 
 - GtkMenuPositionFunc has a new parameter push_in which controls how
   menus placed outside the screen is handled. If this is set to true and
index 96b66d7d1c96a437301893537272a8532f198eac..e2bbb8bcedbd3b3e2967554b9ed2edb00defa255 100644 (file)
@@ -1,3 +1,8 @@
+Wed Oct 25 15:19:40 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/tmpl/gtknotebook.sgml: Moved function docs into .c
+       file, fairly extensive rewriting.
+
 Thu Nov 30 00:53:45 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/tmpl/gtkfilesel.sgml: Fix to say that file_selection_complete()
index 4b73f7b5d19f90b60c477690cf35c2f30a822ed2..a51536f49dea09ad37f9b5bd84e701d385d259ce 100644 (file)
@@ -2,13 +2,21 @@
 GtkNotebook
 
 <!-- ##### SECTION Short_Description ##### -->
-Set of pages with bookmarks.
+A tabbed notebook container.
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
 The #GtkNotebook widget is a #GtkContainer whose children are pages that
-can be accessed through bookmarks. The pages are displayed all at the same
-place. <!-- TODO: talk about the menu -->
+can be switched between using tab labels along one edge.
+</para>
+<para>
+There are many configuration options for #GtkNotebook. Among other
+things, you can choose on which edge the tabs appear
+(see gtk_notebook_set_tab_pos()), whether, if there are too many
+tabs to fit the noteobook should be made bigger or scrolling
+arrows added (see gtk_notebook_set_scrollable), and whether there
+will be a popup menu allowing the users to switch pages.
+(see gtk_notebook_enable_popup(), gtk_noteobook_disable_popup())
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
@@ -28,124 +36,83 @@ place. <!-- TODO: talk about the menu -->
 </para>
 
 
-<!-- ##### MACRO GTK_NOTEBOOK_PAGE ##### -->
-<para>
-Extracts the contents of the current element of #GList @_glist_ as a
-#GtkNotebookPage.
-</para>
-
-@_glist_: 
-
-
 <!-- ##### STRUCT GtkNotebookPage ##### -->
 <para>
-The #GtkNotebookPage structure is used to store the pages of a notebook. It
-is not an object.
+The #GtkNotebookPage is an opaque implementation detail of #GtkNotebook.
 </para>
 
-@child: the contents of the page
-@tab_label: the label shown in the bookmark
-@menu_label: the label shown in the popup menu
-@default_menu: 
-@default_tab: 
-@expand: 
-@fill: 
-@pack: 
-@requisition: 
-@allocation: 
-
 <!-- ##### FUNCTION gtk_notebook_new ##### -->
 <para>
-Creates a new #GtkNotebook widget
 </para>
 
-@Returns: the newly created G=#GtkNotebook
+@Returns: 
 
 
 <!-- ##### FUNCTION gtk_notebook_append_page ##### -->
 <para>
-Appends to @notebook a page whose content is @child, and whose bookmark is
-@tab_label.
 </para>
 
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark for the page
+@notebook:
+@child:
+@tab_label:
 
 
 <!-- ##### FUNCTION gtk_notebook_append_page_menu ##### -->
 <para>
-Appends to @notebook a page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label.
 </para>
 
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@menu_label: the menu label of the page
+@notebook:
+@child:
+@tab_label:
+@menu_label:
 
 
 <!-- ##### FUNCTION gtk_notebook_prepend_page ##### -->
 <para>
-Prepends to @notebook a page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label.
 </para>
 
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
+@notebook:
+@child: the 
+@tab_label:
 
 
 <!-- ##### FUNCTION gtk_notebook_prepend_page_menu ##### -->
 <para>
-Appends to @notebook a page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label.
 </para>
 
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@menu_label: the menu label of the page
+@notebook: 
+@child: 
+@tab_label:
+@menu_label:
 
 
 <!-- ##### FUNCTION gtk_notebook_insert_page ##### -->
 <para>
-Inserts in @notebook a new page whose content is @child, and whose
-bookmark is @tab_label. The page is inserted just
-before the page number @position, starting with 0. If @position is out of
-bounds, it is assumed to be the current number of pages.
 </para>
 
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@position: the position to insert the page
+@notebook:
+@child:
+@tab_label:
+@position:
 
 
 <!-- ##### FUNCTION gtk_notebook_insert_page_menu ##### -->
 <para>
-Inserts in @notebook a new page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label. The page is inserted just
-before the page number @position, starting with 0. If @position is out of
-bounds, it is assumed to be the current number of pages.
 </para>
 
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@menu_label: the menu label of the page
-@position: the position to insert the page
+@notebook:
+@child:
+@tab_label:
+@menu_label: 
+@position:
 
 
 <!-- ##### FUNCTION gtk_notebook_remove_page ##### -->
 <para>
-Removes the page @page_num form @notebook. Pages are numbered starting at
-zero. Negative values stand for the last page; too large values are
-ignored.
 </para>
 
-@notebook: the notebook widget
-@page_num: the page number
+@notebook: 
+@page_num:
 
 
 <!-- ##### MACRO gtk_notebook_current_page ##### -->
@@ -157,56 +124,45 @@ Compatibility macro; in gtkcompat.h.
 
 <!-- ##### FUNCTION gtk_notebook_page_num ##### -->
 <para>
-Returns the page number of @child in @notebook.
 </para>
 
-@notebook: the notebook widget
-@child: the child
-@Returns: the page number, or -1 if @child is not in @notebook
+@notebook:
+@child:
+@Returns:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_page ##### -->
 <para>
-Switches to the page number @page_num. Negative values stand for the last
-page; too large values are ignored.
 </para>
 
-@notebook: the notebook widget
-@page_num: the page number
+@notebook:
+@page_num:
 
 
 <!-- ##### FUNCTION gtk_notebook_next_page ##### -->
 <para>
-Switches to the next page. Nothing happens if the current page is the last
-page.
 </para>
 
-@notebook: the notebook widget.
+@notebook:
 
 
 <!-- ##### FUNCTION gtk_notebook_prev_page ##### -->
 <para>
-Switches to the previous page. Nothing happens if the current page is the
-first page.
 </para>
 
-@notebook: the notebook widget
+@notebook:
 
 
 <!-- ##### FUNCTION gtk_notebook_reorder_child ##### -->
 <para>
-Moves the page @child, so that it appears in position @position. Out of
-bounds @position will be clamped.
 </para>
 
-@notebook: the notebook widget
-@child: the child to deplace
-@position: the new position
-
+@notebook
+@child:
+@position:
 
 <!-- ##### FUNCTION gtk_notebook_set_tab_pos ##### -->
 <para>
-Sets the position of the bookmarks.
 </para>
 
 @notebook: the notebook widget
@@ -215,62 +171,51 @@ Sets the position of the bookmarks.
 
 <!-- ##### FUNCTION gtk_notebook_set_show_tabs ##### -->
 <para>
-Sets whether to show the bookmarks or not.
 </para>
 
-@notebook: the notebook widget
-@show_tabs: a boolean value
+@notebook:
+@show_tabs:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_show_border ##### -->
 <para>
-Sets whether to show the border of the notebook or not. Bookmarks are in the
-border.
 </para>
 
-@notebook: the notebook widget
-@show_border: a boolean value
+@notebook:
+@show_border:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_scrollable ##### -->
 <para>
-Sets whether the bookmarks area may be scrollable or not if there are too
-many bookmarks to fit in the allocated area.
 </para>
 
-@notebook: the notebook widget
-@scrollable: a boolean value
+@notebook:
+@scrollable:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_tab_border ##### -->
 <para>
-Sets whether there should be a border around the bookmarks or not.
 </para>
 
-@notebook: the notebook widget
-@border_width: a boolean value
+@notebook:
+@border_width:
 
 
 <!-- ##### FUNCTION gtk_notebook_popup_enable ##### -->
 <para>
-Enables the popup menu: if the user clicks with the right mouse button on
-the bookmarks, a menu with all the pages will be popped up.
 </para>
 
-@notebook: the notebook widget
+@notebook:
 
 
 <!-- ##### FUNCTION gtk_notebook_popup_disable ##### -->
 <para>
-Disables the popup menu
 </para>
 
-@notebook: the notebook widget
-
+@notebook:
 
 <!-- ##### FUNCTION gtk_notebook_get_current_page ##### -->
 <para>
-Returns the page number of the current page.
 </para>
 
 @notebook: the notebook widget
@@ -279,129 +224,108 @@ Returns the page number of the current page.
 
 <!-- ##### FUNCTION gtk_notebook_get_menu_label ##### -->
 <para>
-Returns the menu label of the page @child. NULL is returned if @child is not
-in @notebook or NULL if it has the default menu label.
 </para>
 
-@notebook: the notebook widget
-@child: the page
-@Returns: the menu label
+@notebook: 
+@child: 
+@Returns: 
 
 
 <!-- ##### FUNCTION gtk_notebook_get_nth_page ##### -->
 <para>
-Returns the content of the page number @page_num, or NULL if @page_num is
-out of bounds.
 </para>
 
-@notebook: the notebook widget
-@page_num: the page number
-@Returns: the content of the page
+@notebook:
+@page_num:
+@Returns:
 
 
 <!-- ##### FUNCTION gtk_notebook_get_tab_label ##### -->
 <para>
-Returns the menu tab of the page @child. NULL is returned if @child is not
-in @notebook or NULL if it has the default tab label.
 </para>
 
-@notebook: the notebook widget
-@child: the page
-@Returns: the tab label
+@notebook:
+@child:
+@Returns:
 
 
 <!-- ##### FUNCTION gtk_notebook_query_tab_label_packing ##### -->
 <para>
-Looks for the packing attributes of the bookmarks of @child.
 </para>
 
-@notebook: the notebook widget
-@child: the page
-@expand: a pointer to return the expand value (or NULL)
-@fill: a pointer to return the fill value (or NULL)
-@pack_type: a pointer to return the pack_type (or NULL)
+@notebook:
+@child:
+@expand:
+@fill:
+@pack_type:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_homogeneous_tabs ##### -->
 <para>
-Sets whether the tabs must have all the same size or not.
 </para>
 
-@notebook: the notebook widget
-@homogeneous: a boolean value
+@notebook:
+@homogeneous:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_menu_label ##### -->
 <para>
-Changes the menu label of @child. Nothing happens if @child is not in
-@notebook.
 </para>
 
-@notebook: the notebook widget
-@child: the page
-@menu_label: the menu label, or NULL for default
+@notebook: 
+@child: 
+@menu_label: 
 
 
 <!-- ##### FUNCTION gtk_notebook_set_menu_label_text ##### -->
 <para>
-Creates a new label and sets it as the menu label of @child.
 </para>
 
-@notebook: the notebook widget
-@child: the page
-@menu_text: the label text
 
 
 <!-- ##### FUNCTION gtk_notebook_set_tab_hborder ##### -->
 <para>
-Sets whether the tabs should have a horizontal border.
 </para>
 
-@notebook: the notebook widget
-@tab_hborder: a boolean value
+@notebook:
+@tab_hborder:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_tab_label ##### -->
 <para>
-Changes the bookmark label of @child. Nothing happens if @child is not in
-@notebook.
 </para>
 
-@notebook: the notebook widget
-@child: the page
-@tab_label: the bookmark label, or NULL for default
+@notebook: 
+@child:
+@tab_label:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_tab_label_packing ##### -->
 <para>
-Sets the packing parameters for the bookmark of @child. See
-#GtkBoxPackStart for the exact meanings.
 </para>
 
-@notebook: the notebook widget
-@child: the child widget
-@expand: whether to expand the bookmark or not
-@fill: whether the bookmark should fill the allocated area or not
-@pack_type: the position of the bookmark
+@notebook: 
+@child: 
+@expand:
+@fill: 
+@pack_type:
 
 
 <!-- ##### FUNCTION gtk_notebook_set_tab_label_text ##### -->
 <para>
-Creates a new label and sets it as the bookmark label of @child.
 </para>
 
-@notebook: the notebook widget
-@child: the page
-@tab_text: the label text
+@notebook: 
+@child: 
+@tab_text: 
 
 
 <!-- ##### FUNCTION gtk_notebook_set_tab_vborder ##### -->
 <para>
-Sets whether the tabs should have a vertical border.
 </para>
 
-@notebook: the notebook widget
-@tab_vborder: a boolean value
+@notebook:
+@tab_vborder:
 
 
 <!-- ##### SIGNAL GtkNotebook::switch-page ##### -->
@@ -420,46 +344,47 @@ The current page
 
 <!-- ##### ARG GtkNotebook:tab_pos ##### -->
 <para>
-The position of the bookmarks
+The edge at which the tabs for switching pages are drawn.
 </para>
 
 <!-- ##### ARG GtkNotebook:tab_border ##### -->
 <para>
-Whether the bookmarks have a border or not
+Whether the tab labels have a border on all sides.
 </para>
 
 <!-- ##### ARG GtkNotebook:tab_hborder ##### -->
 <para>
-Whether the bookmarks have a horizontal border or not
+Whether the tab labels have a horizontal border.
 </para>
 
 <!-- ##### ARG GtkNotebook:tab_vborder ##### -->
 <para>
-Whether the bookmarks have a vertical border or not
+Whether the tab labels have a vertical border.
 </para>
 
 <!-- ##### ARG GtkNotebook:show_tabs ##### -->
 <para>
-Whether to show the bookmarks or not
+Whether to show tabs for the notebook pages.
 </para>
 
 <!-- ##### ARG GtkNotebook:show_border ##### -->
 <para>
-Whether to show the border or not
+Whether to draw a bevel around the noteobook.
 </para>
 
 <!-- ##### ARG GtkNotebook:scrollable ##### -->
 <para>
-Whether the bookmarks should be scrollable or not
+Whether the tab label area will have arrows for scrolling if there
+are too many tabs to fit in the area.
 </para>
 
 <!-- ##### ARG GtkNotebook:enable_popup ##### -->
 <para>
-Whether the popup menu is enabled or not
+Whether the popup menu for switching pages is enabled.
 </para>
 
 <!-- ##### ARG GtkNotebook:homogeneous ##### -->
 <para>
-
+whether the tabs must have all the same size.
 </para>
 
index 07a5532db6b80f315e84a03b192e2dc0cca66906..1c6428af11c1e2a67e4f3d8aa517995ac18db963 100644 (file)
@@ -150,15 +150,6 @@ GTK_USER_STYLE:
        wich share a global user style from the ones which got a certain
        style assign from outside the toolkit.
        
-GTK_REDRAW_PENDING:
-       Relies on GTK_WIDGET_MAPPED (widget).
-       [FIXME: this is not really enforced throughout the code, but should
-        be. it only requires a few checks for GTK_WIDGET_MAPPED and
-        minor changes to gtk_widget_unmap, we can then remove the check
-        in gtk_widget_real_destroy]
-       Means: there is an idle handler waiting for the widget, that
-       will cause a full redraw (gtk_widget_draw (widget, NULL)).
-
 GTK_RESIZE_PENDING:
        First, this is only valid for GtkContainers.
        [some of the code should move to gtkcontainer.c therefore]
@@ -245,7 +236,7 @@ In the following
 Note:, the definition
 
 [  GTK_WIDGET_DRAWABLE = GTK_WIDGET_VISIBLE && GTK_WIDGET_MAPPED
-   is made in gtkwidget.c, but by 3) and 5), 
+   is made in gtkwidget.h, but by 3) and 5), 
      
       GTK_WIDGET_MAPPED => GTK_WIDGET_VISIBLE
 ]
index 8d83c47f1bc7c75a0af89ce09c984e53d33f7ef0..ab5ca5edfa42c780d7b0f474dbcdc69afc312f7c 100644 (file)
@@ -198,8 +198,6 @@ static void gtk_clist_map             (GtkWidget        *widget);
 static void gtk_clist_unmap           (GtkWidget        *widget);
 static gint gtk_clist_expose          (GtkWidget        *widget,
                                       GdkEventExpose   *event);
-static gint gtk_clist_key_press       (GtkWidget        *widget,
-                                      GdkEventKey      *event);
 static gint gtk_clist_button_press    (GtkWidget        *widget,
                                       GdkEventButton   *event);
 static gint gtk_clist_button_release  (GtkWidget        *widget,
@@ -217,6 +215,8 @@ static gint gtk_clist_focus_out       (GtkWidget        *widget,
                                       GdkEventFocus    *event);
 static gint gtk_clist_focus           (GtkContainer     *container,
                                       GtkDirectionType  direction);
+static void gtk_clist_set_focus_child (GtkContainer     *container,
+                                      GtkWidget        *child);
 static void gtk_clist_style_set       (GtkWidget        *widget,
                                       GtkStyle         *previous_style);
 static void gtk_clist_drag_begin      (GtkWidget        *widget,
@@ -250,8 +250,6 @@ static void gtk_clist_drag_data_received (GtkWidget        *widget,
                                          guint             time);
 
 /* GtkContainer Methods */
-static void gtk_clist_set_focus_child (GtkContainer  *container,
-                                      GtkWidget     *child);
 static void gtk_clist_forall          (GtkContainer  *container,
                                       gboolean       include_internals,
                                       GtkCallback    callback,
@@ -438,8 +436,11 @@ static GList *gtk_clist_mergesort  (GtkCList      *clist,
                                    GList         *list,
                                    gint           num);
 /* Misc */
-static gboolean title_focus           (GtkCList  *clist,
-                                      gint       dir);
+static gboolean title_focus_in   (GtkCList *clist,
+                                 gint      dir);
+static gboolean title_focus_move (GtkCList *clist,
+                                 gint      dir);
+
 static void real_row_move             (GtkCList  *clist,
                                       gint       source_row,
                                       gint       dest_row);
@@ -675,7 +676,6 @@ gtk_clist_class_init (GtkCListClass *klass)
   widget_class->expose_event = gtk_clist_expose;
   widget_class->size_request = gtk_clist_size_request;
   widget_class->size_allocate = gtk_clist_size_allocate;
-  widget_class->key_press_event = gtk_clist_key_press;
   widget_class->focus_in_event = gtk_clist_focus_in;
   widget_class->focus_out_event = gtk_clist_focus_out;
   widget_class->draw_focus = gtk_clist_draw_focus;
@@ -921,7 +921,6 @@ gtk_clist_init (GtkCList *clist)
 
   GTK_WIDGET_UNSET_FLAGS (clist, GTK_NO_WINDOW);
   GTK_WIDGET_SET_FLAGS (clist, GTK_CAN_FOCUS);
-  GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
   GTK_CLIST_SET_FLAG (clist, CLIST_DRAW_DRAG_LINE);
   GTK_CLIST_SET_FLAG (clist, CLIST_USE_DRAG_ICONS);
 
@@ -973,6 +972,7 @@ gtk_clist_init (GtkCList *clist)
   clist->undo_unselection = NULL;
 
   clist->focus_row = -1;
+  clist->focus_header_column = -1;
   clist->undo_anchor = -1;
 
   clist->anchor = -1;
@@ -4425,7 +4425,6 @@ gtk_clist_finalize (GObject *object)
  *   gtk_clist_unmap
  *   gtk_clist_expose
  *   gtk_clist_style_set
- *   gtk_clist_key_press
  *   gtk_clist_button_press
  *   gtk_clist_button_release
  *   gtk_clist_motion
@@ -4466,7 +4465,6 @@ gtk_clist_realize (GtkWidget *widget)
   attributes.event_mask |= (GDK_EXPOSURE_MASK |
                            GDK_BUTTON_PRESS_MASK |
                            GDK_BUTTON_RELEASE_MASK |
-                           GDK_KEY_PRESS_MASK |
                            GDK_KEY_RELEASE_MASK);
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
@@ -4524,8 +4522,7 @@ gtk_clist_realize (GtkWidget *widget)
   attributes.event_mask = (GDK_BUTTON_PRESS_MASK |
                           GDK_BUTTON_RELEASE_MASK |
                           GDK_POINTER_MOTION_MASK |
-                          GDK_POINTER_MOTION_HINT_MASK |
-                          GDK_KEY_PRESS_MASK);
+                          GDK_POINTER_MOTION_HINT_MASK);
   attributes_mask = GDK_WA_CURSOR;
   attributes.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
   clist->cursor_drag = attributes.cursor;
@@ -4841,34 +4838,6 @@ gtk_clist_style_set (GtkWidget *widget,
     }
 }
 
-static gint
-gtk_clist_key_press (GtkWidget   *widget,
-                    GdkEventKey *event)
-{
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_CLASS (parent_class)->key_press_event &&
-      GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
-    return TRUE;
-
-  switch (event->keyval)
-    {
-    case GDK_Tab:
-    case GDK_ISO_Left_Tab:
-      if (event->state & GDK_SHIFT_MASK)
-       return gtk_container_focus (GTK_CONTAINER (widget),
-                                   GTK_DIR_TAB_BACKWARD);
-      else
-       return gtk_container_focus (GTK_CONTAINER (widget),
-                                   GTK_DIR_TAB_FORWARD);
-    default:
-      break;
-    }
-  return FALSE;
-}
-
 static gint
 gtk_clist_button_press (GtkWidget      *widget,
                        GdkEventButton *event)
@@ -6196,6 +6165,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
                           gpointer       data)
 {
   GtkCList *clist;
+  GtkContainer *container;
   GdkRectangle area;
   gint i;
   gint y = 0;
@@ -6207,6 +6177,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
   g_return_if_fail (GTK_IS_CLIST (data));
 
   clist = GTK_CLIST (data);
+  container = GTK_CONTAINER (data);
 
   if (!GTK_WIDGET_DRAWABLE (clist) || adjustment != clist->hadjustment)
     return;
@@ -6250,7 +6221,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
        }
 
       if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
-         !GTK_CLIST_CHILD_HAS_FOCUS(clist) && GTK_CLIST_ADD_MODE(clist))
+         !container->focus_child && GTK_CLIST_ADD_MODE(clist))
        {
          y = ROW_TOP_YPIXEL (clist, clist->focus_row);
              
@@ -6285,7 +6256,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
        }
       
       if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
-         !GTK_CLIST_CHILD_HAS_FOCUS(clist) && GTK_CLIST_ADD_MODE(clist))
+         !container->focus_child && GTK_CLIST_ADD_MODE(clist))
        {
          y = ROW_TOP_YPIXEL (clist, clist->focus_row);
          
@@ -6313,7 +6284,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
   check_exposures (clist);
 
   if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
-      !GTK_CLIST_CHILD_HAS_FOCUS(clist))
+      !container->focus_child)
     {
       if (GTK_CLIST_ADD_MODE(clist))
        {
@@ -6503,108 +6474,114 @@ row_delete (GtkCList    *clist,
 }
 
 /* FOCUS FUNCTIONS
+ *   gtk_clist_focus_content_area
  *   gtk_clist_focus
  *   gtk_clist_draw_focus
  *   gtk_clist_focus_in
  *   gtk_clist_focus_out
- *   gtk_clist_set_focus_child
  *   title_focus
  */
-static gint
+static void
+gtk_clist_focus_content_area (GtkCList *clist)
+{
+  if (clist->focus_row < 0)
+    {
+      clist->focus_row = 0;
+      
+      if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
+          clist->selection_mode == GTK_SELECTION_EXTENDED) &&
+         !clist->selection)
+       gtk_signal_emit (GTK_OBJECT (clist),
+                        clist_signals[SELECT_ROW],
+                        clist->focus_row, -1, NULL);
+    }
+  gtk_widget_grab_focus (GTK_WIDGET (clist));
+}
+
+static gboolean
 gtk_clist_focus (GtkContainer     *container,
                 GtkDirectionType  direction)
 {
-  GtkCList *clist;
-  GtkWidget *focus_child;
-  gint old_row;
-
-  g_return_val_if_fail (container != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_CLIST (container), FALSE);
+  GtkCList *clist = GTK_CLIST (container);
+  GtkWidget *focus_child = container->focus_child;
+  gboolean is_current_focus;
 
   if (!GTK_WIDGET_IS_SENSITIVE (container))
     return FALSE;
-  
-  clist = GTK_CLIST (container);
-  focus_child = container->focus_child;
-  old_row = clist->focus_row;
 
+  is_current_focus = gtk_widget_is_focus (GTK_WIDGET (clist));
+                         
+  if (focus_child &&
+      GTK_IS_CONTAINER (focus_child) &&
+      GTK_WIDGET_DRAWABLE (focus_child) &&
+      GTK_WIDGET_IS_SENSITIVE (focus_child) &&
+      gtk_container_focus (GTK_CONTAINER (focus_child), direction))
+    return TRUE;
+      
   switch (direction)
     {
     case GTK_DIR_LEFT:
     case GTK_DIR_RIGHT:
-      if (GTK_CLIST_CHILD_HAS_FOCUS(clist))
+      if (focus_child)
        {
-         if (title_focus (clist, direction))
+         if (title_focus_move (clist, direction))
            return TRUE;
-         gtk_container_set_focus_child (container, NULL);
-         return FALSE;
-        }
-      gtk_widget_grab_focus (GTK_WIDGET (container));
-      return TRUE;
+       }
+      else if (!is_current_focus)
+       {
+         gtk_clist_focus_content_area (clist);
+         return TRUE;
+       }
+      break;
     case GTK_DIR_DOWN:
     case GTK_DIR_TAB_FORWARD:
-      if (GTK_CLIST_CHILD_HAS_FOCUS(clist))
+      if (!focus_child && !is_current_focus)
        {
-         gboolean tf = FALSE;
-
-         if (((focus_child && direction == GTK_DIR_DOWN) ||
-              !(tf = title_focus (clist, GTK_DIR_TAB_FORWARD)))
-             && clist->rows)
-           {
-             if (clist->focus_row < 0)
-               {
-                 clist->focus_row = 0;
-
-                 if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
-                      clist->selection_mode == GTK_SELECTION_EXTENDED) &&
-                     !clist->selection)
-                   gtk_signal_emit (GTK_OBJECT (clist),
-                                    clist_signals[SELECT_ROW],
-                                    clist->focus_row, -1, NULL);
-               }
-             gtk_widget_grab_focus (GTK_WIDGET (container));
-             return TRUE;
-           }
-
-         if (tf)
+         if (title_focus_in (clist, direction))
            return TRUE;
        }
       
-      GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
+      if (!is_current_focus && clist->rows)
+       {
+         gtk_clist_focus_content_area (clist);
+         return TRUE;
+       }
       break;
     case GTK_DIR_UP:
     case GTK_DIR_TAB_BACKWARD:
-      if (!focus_child &&
-         GTK_CLIST_CHILD_HAS_FOCUS(clist) && clist->rows)
+      if (!focus_child && is_current_focus)
        {
-         if (clist->focus_row < 0)
-           {
-             clist->focus_row = 0;
-             if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
-                  clist->selection_mode == GTK_SELECTION_EXTENDED) &&
-                 !clist->selection)
-               gtk_signal_emit (GTK_OBJECT (clist),
-                                clist_signals[SELECT_ROW],
-                                clist->focus_row, -1, NULL);
-           }
-         gtk_widget_grab_focus (GTK_WIDGET (container));
+         if (title_focus_in (clist, direction))
+           return TRUE;
+       }
+      
+      if (!is_current_focus && !focus_child && clist->rows)
+       {
+         gtk_clist_focus_content_area (clist);
          return TRUE;
        }
-
-      GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
-
-      if (title_focus (clist, direction))
-       return TRUE;
-
       break;
     default:
       break;
     }
 
-  gtk_container_set_focus_child (container, NULL);
   return FALSE;
 }
 
+static void
+gtk_clist_set_focus_child (GtkContainer *container,
+                          GtkWidget    *child)
+{
+  GtkCList *clist = GTK_CLIST (container);
+  gint i;
+
+  for (i = 0; i < clist->columns; i++)
+    if (clist->column[i].button == child)
+      clist->focus_header_column = i;
+  
+  parent_class->set_focus_child (container, child);
+}
+
 static void
 gtk_clist_draw_focus (GtkWidget *widget)
 {
@@ -6635,7 +6612,6 @@ gtk_clist_focus_in (GtkWidget     *widget,
   g_return_val_if_fail (event != NULL, FALSE);
 
   GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
-  GTK_CLIST_UNSET_FLAG (widget, CLIST_CHILD_HAS_FOCUS);
 
   clist = GTK_CLIST (widget);
 
@@ -6668,7 +6644,6 @@ gtk_clist_focus_out (GtkWidget     *widget,
   g_return_val_if_fail (event != NULL, FALSE);
 
   GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
-  GTK_CLIST_SET_FLAG (widget, CLIST_CHILD_HAS_FOCUS);
 
   gtk_widget_draw_focus (widget);
   
@@ -6679,123 +6654,154 @@ gtk_clist_focus_out (GtkWidget     *widget,
   return FALSE;
 }
 
-static void
-gtk_clist_set_focus_child (GtkContainer *container,
-                          GtkWidget    *child)
+static gboolean
+focus_column (GtkCList *clist, gint column, gint dir)
 {
-  g_return_if_fail (container != NULL);
-  g_return_if_fail (GTK_IS_CLIST (container));
+  GtkWidget *child = clist->column[column].button;
+  
+  if (GTK_IS_CONTAINER (child) &&
+      gtk_container_focus (GTK_CONTAINER (child), dir))
+    {
+      return TRUE;
+    }
+  else if (GTK_WIDGET_CAN_FOCUS (child))
+    {
+      gtk_widget_grab_focus (child);
+      return TRUE;
+    }
 
-  if (child)
+  return FALSE;
+}
+
+/* Focus moved onto the headers. Focus first focusable and visible child.
+ * (FIXME: focus the last focused child if visible)
+ */
+static gboolean
+title_focus_in (GtkCList *clist, gint dir)
+{
+  gint i;
+  gint left, right;
+
+  /* Check last focused column */
+  if (clist->focus_header_column != -1)
+    {
+      i = clist->focus_header_column;
+      
+      left = COLUMN_LEFT_XPIXEL (clist, i);
+      right = left + clist->column[i].area.width;
+      
+      if (left >= 0 && right <= clist->clist_window_width)
+       {
+         if (focus_column (clist, i, dir))
+           return TRUE;
+       }
+    }
+
+  /* Check fully visible columns */
+  for (i = 0 ; i < clist->columns ; i++)
     {
-      g_return_if_fail (GTK_IS_WIDGET (child));
-      GTK_CLIST_SET_FLAG (container, CLIST_CHILD_HAS_FOCUS);
+      left = COLUMN_LEFT_XPIXEL (clist, i);
+      right = left + clist->column[i].area.width;
+      
+      if (left >= 0 && right <= clist->clist_window_width)
+       {
+         if (focus_column (clist, i, dir))
+           return TRUE;
+       }
     }
 
-  parent_class->set_focus_child (container, child);
+  /* Check partially visible columns */
+  for (i = 0 ; i < clist->columns ; i++)
+    {
+      left = COLUMN_LEFT_XPIXEL (clist, i);
+      right = left + clist->column[i].area.width;
+
+      if ((left < 0 && right > 0) ||
+         (left < clist->clist_window_width && right > clist->clist_window_width))
+       {
+         if (focus_column (clist, i, dir))
+           return TRUE;
+       }
+    }
+      
+  return FALSE;
 }
 
+/* Move the focus right or left within the title buttons, scrolling
+ * as necessary to keep the focused child visible.
+ */
 static gboolean
-title_focus (GtkCList *clist,
-            gint      dir)
+title_focus_move (GtkCList *clist,
+                 gint      dir)
 {
   GtkWidget *focus_child;
   gboolean return_val = FALSE;
-  gint last_column;
-  gint d = 1;
-  gint i = 0;
+  gint d = 0;
+  gint i = -1;
   gint j;
 
   if (!GTK_CLIST_SHOW_TITLES(clist))
     return FALSE;
 
   focus_child = GTK_CONTAINER (clist)->focus_child;
+  g_assert (focus_child);
 
-  for (last_column = clist->columns - 1;
-       last_column >= 0 && !clist->column[last_column].visible; last_column--)
-    ;
-  
+  /* Movement direction within headers
+   */
   switch (dir)
     {
-    case GTK_DIR_TAB_BACKWARD:
-    case GTK_DIR_UP:
-      if (!focus_child || !GTK_CLIST_CHILD_HAS_FOCUS(clist))
-       {
-         if (dir == GTK_DIR_UP)
-           i = COLUMN_FROM_XPIXEL (clist, 0);
-         else
-           i = last_column;
-         focus_child = clist->column[i].button;
-         dir = GTK_DIR_TAB_FORWARD;
-       }
-      else
-       d = -1;
+    case GTK_DIR_RIGHT:
+      d = 1;
       break;
     case GTK_DIR_LEFT:
       d = -1;
-      if (!focus_child)
-       {
-         i = last_column;
-         focus_child = clist->column[i].button;
-       }
       break;
-    case GTK_DIR_RIGHT:
-      if (!focus_child)
+    }
+  
+  for (i = 0; i < clist->columns; i++)
+    if (clist->column[i].button == focus_child)
+      break;
+  
+  g_assert (i != -1);          /* Have a starting column */
+  
+  j = i + d;
+  while (!return_val && j >= 0 && j < clist->columns)
+    {
+      if (clist->column[j].button &&
+         GTK_WIDGET_VISIBLE (clist->column[j].button))
        {
-         i = 0;
-         focus_child = clist->column[i].button;
+         if (focus_column (clist, j, dir))
+           {
+             return_val = TRUE;
+             break;
+           }
        }
-      break;
+      j += d;
     }
 
-  if (focus_child)
-    while (i < clist->columns)
-      {
-       if (clist->column[i].button == focus_child)
-         {
-           if (clist->column[i].button && 
-               GTK_WIDGET_VISIBLE (clist->column[i].button) &&
-               GTK_IS_CONTAINER (clist->column[i].button) &&
-               !GTK_WIDGET_HAS_FOCUS(clist->column[i].button))
-             if (gtk_container_focus 
-                 (GTK_CONTAINER (clist->column[i].button), dir))
+  /* If we didn't find it, wrap around and keep looking
+   */
+  if (!return_val)
+    {
+      j = d > 0 ? 0 : clist->columns - 1;
+
+      while (!return_val && j != i)
+       {
+         if (clist->column[j].button &&
+             GTK_WIDGET_VISIBLE (clist->column[j].button))
+           {
+             if (focus_column (clist, j, dir))
                {
                  return_val = TRUE;
-                 i -= d;
+                 break;
                }
-           if (!return_val && dir == GTK_DIR_UP)
-             return FALSE;
-           i += d;
-           break;
-         }
-       i++;
-      }
-
-  j = i;
+           }
+         j += d;
+       }
+    }
 
-  if (!return_val)
-    while (j >= 0 && j < clist->columns)
-      {
-       if (clist->column[j].button &&
-           GTK_WIDGET_VISIBLE (clist->column[j].button))
-         {
-           if (GTK_IS_CONTAINER (clist->column[j].button) &&
-               gtk_container_focus 
-               (GTK_CONTAINER (clist->column[j].button), dir))
-             {
-               return_val = TRUE;
-               break;
-             }
-           else if (GTK_WIDGET_CAN_FOCUS (clist->column[j].button))
-             {
-               gtk_widget_grab_focus (clist->column[j].button);
-               return_val = TRUE;
-               break;
-             }
-         }
-       j += d;
-      }
-  
+  /* Scroll horizontally so focused column is visible
+   */
   if (return_val)
     {
       if (COLUMN_LEFT_XPIXEL (clist, j) < CELL_SPACING + COLUMN_INSET)
@@ -6803,13 +6809,20 @@ title_focus (GtkCList *clist,
       else if (COLUMN_LEFT_XPIXEL(clist, j) + clist->column[j].area.width >
               clist->clist_window_width)
        {
+         gint last_column;
+         
+         for (last_column = clist->columns - 1;
+              last_column >= 0 && !clist->column[last_column].visible; last_column--);
+
          if (j == last_column)
            gtk_clist_moveto (clist, -1, j, 0, 0);
          else
            gtk_clist_moveto (clist, -1, j, 0, 1);
        }
     }
-  return return_val;
+  return TRUE;                 /* Even if we didn't find a new one, we can keep the
+                                * focus in the same place.
+                                */
 }
 
 /* PRIVATE SCROLLING FUNCTIONS
index 7bd437c4040a5168ce4d201538ba8f1113d79c78..8de30f6927ed9df970cb981e8da6f4bf334a6f72 100644 (file)
@@ -46,7 +46,7 @@ enum {
   GTK_CLIST_IN_DRAG             = 1 <<  0,
   GTK_CLIST_ROW_HEIGHT_SET      = 1 <<  1,
   GTK_CLIST_SHOW_TITLES         = 1 <<  2,
-  GTK_CLIST_CHILD_HAS_FOCUS     = 1 <<  3,
+  /* Unused */
   GTK_CLIST_ADD_MODE            = 1 <<  4,
   GTK_CLIST_AUTO_SORT           = 1 <<  5,
   GTK_CLIST_AUTO_RESIZE_BLOCKED = 1 <<  6,
@@ -97,7 +97,6 @@ typedef enum
 #define GTK_CLIST_IN_DRAG(clist)           (GTK_CLIST_FLAGS (clist) & GTK_CLIST_IN_DRAG)
 #define GTK_CLIST_ROW_HEIGHT_SET(clist)    (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ROW_HEIGHT_SET)
 #define GTK_CLIST_SHOW_TITLES(clist)       (GTK_CLIST_FLAGS (clist) & GTK_CLIST_SHOW_TITLES)
-#define GTK_CLIST_CHILD_HAS_FOCUS(clist)   (GTK_CLIST_FLAGS (clist) & GTK_CLIST_CHILD_HAS_FOCUS)
 #define GTK_CLIST_ADD_MODE(clist)          (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ADD_MODE)
 #define GTK_CLIST_AUTO_SORT(clist)         (GTK_CLIST_FLAGS (clist) & GTK_CLIST_AUTO_SORT)
 #define GTK_CLIST_AUTO_RESIZE_BLOCKED(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_AUTO_RESIZE_BLOCKED)
@@ -225,6 +224,8 @@ struct _GtkCList
   
   /* focus handling */
   gint focus_row;
+
+  gint focus_header_column;
   
   /* dragging the selection */
   gint anchor;
index 053a6a893a963099a0ceaac7e8fb65ba71176472..d3ee4fbffa36e4bcc967463fb9fe31da248ef173 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <stdarg.h>
 #include <string.h>
+#include <stdlib.h>
+
 #include "gtkcontainer.h"
 #include "gtkprivate.h"
 #include "gtksignal.h"
 #include "gtkmain.h"
-#include <stdarg.h>
-
+#include "gtkwindow.h"
 
 enum {
   ADD,
@@ -59,41 +61,42 @@ struct _GtkChildArgInfo
   guint seq_id;
 };
 
-static void gtk_container_base_class_init   (GtkContainerClass *klass);
-static void gtk_container_class_init        (GtkContainerClass *klass);
-static void gtk_container_init              (GtkContainer      *container);
-static void gtk_container_destroy           (GtkObject         *object);
-static void gtk_container_get_arg           (GtkObject        *object,
-                                            GtkArg            *arg,
-                                            guint              arg_id);
-static void gtk_container_set_arg           (GtkObject        *object,
-                                            GtkArg            *arg,
-                                            guint              arg_id);
-static void gtk_container_add_unimplemented (GtkContainer      *container,
-                                            GtkWidget         *widget);
-static void gtk_container_remove_unimplemented (GtkContainer   *container,
-                                               GtkWidget      *widget);
-static void gtk_container_real_check_resize (GtkContainer      *container);
-static gint gtk_container_real_focus        (GtkContainer      *container,
-                                            GtkDirectionType   direction);
-static void gtk_container_real_set_focus_child (GtkContainer      *container,
-                                            GtkWidget         *widget);
-static gint gtk_container_focus_tab         (GtkContainer      *container,
-                                            GList             *children,
-                                            GtkDirectionType   direction);
-static gint gtk_container_focus_up_down     (GtkContainer      *container,
-                                            GList             *children,
-                                            GtkDirectionType   direction);
-static gint gtk_container_focus_left_right  (GtkContainer      *container,
-                                            GList             *children,
-                                            GtkDirectionType   direction);
-static gint gtk_container_focus_move        (GtkContainer      *container,
-                                            GList             *children,
-                                            GtkDirectionType   direction);
-static void gtk_container_children_callback (GtkWidget         *widget,
-                                             gpointer           client_data);
-static void gtk_container_show_all          (GtkWidget         *widget);
-static void gtk_container_hide_all          (GtkWidget         *widget);
+static void     gtk_container_base_class_init      (GtkContainerClass *klass);
+static void     gtk_container_class_init           (GtkContainerClass *klass);
+static void     gtk_container_init                 (GtkContainer      *container);
+static void     gtk_container_destroy              (GtkObject         *object);
+static void     gtk_container_get_arg              (GtkObject         *object,
+                                                   GtkArg            *arg,
+                                                   guint              arg_id);
+static void     gtk_container_set_arg              (GtkObject         *object,
+                                                   GtkArg            *arg,
+                                                   guint              arg_id);
+static void     gtk_container_add_unimplemented    (GtkContainer      *container,
+                                                   GtkWidget         *widget);
+static void     gtk_container_remove_unimplemented (GtkContainer      *container,
+                                                   GtkWidget         *widget);
+static void     gtk_container_real_check_resize    (GtkContainer      *container);
+static gboolean gtk_container_real_focus           (GtkContainer      *container,
+                                                   GtkDirectionType   direction);
+static void     gtk_container_real_set_focus_child (GtkContainer      *container,
+                                                   GtkWidget         *widget);
+static gboolean gtk_container_focus_tab            (GtkContainer      *container,
+                                                   GList             *children,
+                                                   GtkDirectionType   direction);
+static gboolean gtk_container_focus_up_down        (GtkContainer      *container,
+                                                   GList            **children,
+                                                   GtkDirectionType   direction);
+static gboolean gtk_container_focus_left_right     (GtkContainer      *container,
+                                                   GList            **children,
+                                                   GtkDirectionType   direction);
+static gboolean gtk_container_focus_move           (GtkContainer      *container,
+                                                   GList             *children,
+                                                   GtkDirectionType   direction);
+static void     gtk_container_children_callback    (GtkWidget         *widget,
+                                                   gpointer           client_data);
+static void     gtk_container_show_all             (GtkWidget         *widget);
+static void     gtk_container_hide_all             (GtkWidget         *widget);
+
 
 static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
                                                          GtkWidget    *child);
@@ -1182,7 +1185,7 @@ gtk_container_foreach_full (GtkContainer       *container,
     notify (callback_data);
 }
 
-gint
+gboolean
 gtk_container_focus (GtkContainer     *container,
                     GtkDirectionType  direction)
 {
@@ -1342,7 +1345,7 @@ gtk_container_real_set_focus_child (GtkContainer     *container,
     }
 }
 
-static gint
+static gboolean
 gtk_container_real_focus (GtkContainer     *container,
                          GtkDirectionType  direction)
 {
@@ -1364,8 +1367,11 @@ gtk_container_real_focus (GtkContainer     *container,
 
   if (GTK_WIDGET_CAN_FOCUS (container))
     {
-      gtk_widget_grab_focus (GTK_WIDGET (container));
-      return_val = TRUE;
+      if (!GTK_WIDGET_HAS_FOCUS (container))
+       {
+         gtk_widget_grab_focus (GTK_WIDGET (container));
+         return_val = TRUE;
+       }
     }
   else
     {
@@ -1407,11 +1413,11 @@ gtk_container_real_focus (GtkContainer     *container,
              break;
            case GTK_DIR_UP:
            case GTK_DIR_DOWN:
-             return_val = gtk_container_focus_up_down (container, children, direction);
+             return_val = gtk_container_focus_up_down (container, &children, direction);
              break;
            case GTK_DIR_LEFT:
            case GTK_DIR_RIGHT:
-             return_val = gtk_container_focus_left_right (container, children, direction);
+             return_val = gtk_container_focus_left_right (container, &children, direction);
              break;
            }
 
@@ -1422,7 +1428,7 @@ gtk_container_real_focus (GtkContainer     *container,
   return return_val;
 }
 
-static gint
+static gboolean
 gtk_container_focus_tab (GtkContainer     *container,
                         GList            *children,
                         GtkDirectionType  direction)
@@ -1493,227 +1499,285 @@ gtk_container_focus_tab (GtkContainer     *container,
   return gtk_container_focus_move (container, children, direction);
 }
 
-static gint
-gtk_container_focus_up_down (GtkContainer     *container,
-                            GList            *children,
-                            GtkDirectionType  direction)
+static gboolean
+old_focus_coords (GtkContainer *container, GdkRectangle *old_focus_rect)
 {
-  GtkWidget *child;
-  GtkWidget *child2;
-  GList *tmp_list;
-  gint dist1, dist2;
-  gint focus_x;
-  gint focus_width;
-  guint length;
-  guint i, j;
-
-  /* return failure if there isn't a focus child */
-  if (container->focus_child)
+  GtkWidget *widget = GTK_WIDGET (container);
+  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+  
+  if (toplevel &&
+      GTK_IS_WINDOW (toplevel) && GTK_WINDOW (toplevel)->focus_widget &&
+      GTK_WIDGET_REALIZED (container) &&
+      GTK_WIDGET_REALIZED (GTK_WINDOW (toplevel)->focus_widget))
     {
-      focus_width = container->focus_child->allocation.width / 2;
-      focus_x = container->focus_child->allocation.x + focus_width;
+      GtkWidget *old_focus = GTK_WINDOW (toplevel)->focus_widget;
+      GdkWindow *old_parent_window = old_focus->parent ? old_focus->parent->window : old_focus->window;
+      GdkWindow *new_parent_window = widget->window;
+      GdkWindow *toplevel_window = toplevel->window;
+      
+      *old_focus_rect = old_focus->allocation;
+      
+      /* Translate coordinates to the toplevel */
+      
+      while (old_parent_window != toplevel_window)
+       {
+         gint dx, dy;
+         
+         gdk_window_get_position (old_parent_window, &dx, &dy);
+         
+         old_focus_rect->x += dx;
+         old_focus_rect->y += dy;
+         
+         old_parent_window = gdk_window_get_parent (old_parent_window);
+       }
+      
+      /* Translate coordinates back to the new container */
+      
+      while (new_parent_window != toplevel_window)
+       {
+         gint dx, dy;
+         
+         gdk_window_get_position (new_parent_window, &dx, &dy);
+         
+         old_focus_rect->x -= dx;
+         old_focus_rect->y -= dy;
+         
+         new_parent_window = gdk_window_get_parent (new_parent_window);
+       }
+
+      return TRUE;
     }
-  else
+
+  return FALSE;
+}
+
+typedef struct _CompareInfo CompareInfo;
+
+struct _CompareInfo
+{
+  gint x;
+  gint y;
+};
+
+static gint
+up_down_compare (gconstpointer a,
+                gconstpointer b,
+                gpointer      data)
+{
+  const GtkWidget *child1 = a;
+  const GtkWidget *child2 = b;
+  CompareInfo *compare = data;
+
+  gint y1 = child1->allocation.y + child1->allocation.height / 2;
+  gint y2 = child2->allocation.y + child2->allocation.height / 2;
+
+  if (y1 == y2)
     {
-      focus_width = GTK_WIDGET (container)->allocation.width;
-      if (GTK_WIDGET_NO_WINDOW (container))
-       focus_x = GTK_WIDGET (container)->allocation.x;
+      gint x1 = abs (child1->allocation.x + child1->allocation.width / 2 - compare->x);
+      gint x2 = abs (child2->allocation.x + child2->allocation.width / 2 - compare->x);
+
+      if (compare->y < y1)
+       return (x1 < x2) ? -1 : ((x1 == x2) ? 0 : 1);
       else
-       focus_x = 0;
+       return (x1 < x2) ? 1 : ((x1 == x2) ? 0 : -1);
     }
+  else
+    return (y1 < y2) ? -1 : 1;
+}
 
-  length = g_list_length (children);
+static gboolean
+gtk_container_focus_up_down (GtkContainer     *container,
+                            GList           **children,
+                            GtkDirectionType  direction)
+{
+  CompareInfo compare;
+  GList *tmp_list;
 
-  /* sort the children in the y direction */
-  for (i = 1; i < length; i++)
+  if (container->focus_child)
     {
-      j = i;
-      tmp_list = g_list_nth (children, j);
-      child = tmp_list->data;
+      gint compare_x1;
+      gint compare_x2;
+      gint compare_y;
+      
+      /* Delete widgets from list that don't match minimum criteria */
 
-      while (j > 0)
+      compare_x1 = container->focus_child->allocation.x;
+      compare_x2 = container->focus_child->allocation.x + container->focus_child->allocation.width;
+
+      if (direction == GTK_DIR_UP)
+       compare_y = container->focus_child->allocation.y;
+      else
+       compare_y = container->focus_child->allocation.y + container->focus_child->allocation.height;
+      
+      tmp_list = *children;
+      while (tmp_list)
        {
-         child2 = tmp_list->prev->data;
-         if (child->allocation.y < child2->allocation.y)
+         GtkWidget *child = tmp_list->data;
+         GList *next = tmp_list->next;
+         gint child_x1, child_x2;
+         
+         if (child != container->focus_child)
            {
-             tmp_list->data = tmp_list->prev->data;
-             tmp_list = tmp_list->prev;
-             j--;
+             child_x1 = child->allocation.x;
+             child_x2 = child->allocation.x + child->allocation.width;
+             
+             if ((child_x2 <= compare_x1 || child_x1 >= compare_x2) /* No horizontal overlap */ ||
+                 (direction == GTK_DIR_DOWN && child->allocation.y + child->allocation.height < compare_y) || /* Not below */
+                 (direction == GTK_DIR_UP && child->allocation.y > compare_y)) /* Not above */
+               {
+                 *children = g_list_delete_link (*children, tmp_list);
+               }
            }
-         else
-           break;
+         
+         tmp_list = next;
        }
 
-      tmp_list->data = child;
+      compare.x = (compare_x1 + compare_x2) / 2;
+      compare.y = container->focus_child->allocation.y + container->focus_child->allocation.height / 2;
     }
-
-  /* sort the children in distance in the x direction
-   *  in distance from the current focus child while maintaining the
-   *  sort in the y direction
-   */
-  for (i = 1; i < length; i++)
+  else
     {
-      j = i;
-      tmp_list = g_list_nth (children, j);
-      child = tmp_list->data;
-      dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
+      /* No old focus widget, need to figure out starting x,y some other way
+       */
+      GtkWidget *widget = GTK_WIDGET (container);
+      GdkRectangle old_focus_rect;
 
-      while (j > 0)
+      if (old_focus_coords (container, &old_focus_rect))
        {
-         child2 = tmp_list->prev->data;
-         dist2 = (child2->allocation.x + child2->allocation.width / 2) - focus_x;
-
-         if ((dist1 < dist2) &&
-             (child->allocation.y >= child2->allocation.y))
-           {
-             tmp_list->data = tmp_list->prev->data;
-             tmp_list = tmp_list->prev;
-             j--;
-           }
+         compare.x = old_focus_rect.x + old_focus_rect.width / 2;
+       }
+      else
+       {
+         if (GTK_WIDGET_NO_WINDOW (widget))
+           compare.x = widget->allocation.x + widget->allocation.width / 2;
          else
-           break;
+           compare.x = widget->allocation.width / 2;
        }
-
-      tmp_list->data = child;
+      
+      if (GTK_WIDGET_NO_WINDOW (widget))
+       compare.y = (direction == GTK_DIR_DOWN) ? widget->allocation.y : widget->allocation.y + widget->allocation.height;
+      else
+       compare.y = (direction == GTK_DIR_DOWN) ? 0 : + widget->allocation.height;
     }
 
-  /* go and invalidate any widget which is too
-   *  far from the focus widget.
-   */
-  if (!container->focus_child &&
-      (direction == GTK_DIR_UP))
-    focus_x += focus_width;
+  *children = g_list_sort_with_data (*children, up_down_compare, &compare);
 
-  tmp_list = children;
-  while (tmp_list)
-    {
-      child = tmp_list->data;
+  if (direction == GTK_DIR_UP)
+    *children = g_list_reverse (*children);
 
-      dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
-      if (((direction == GTK_DIR_DOWN) && (dist1 < 0)) ||
-         ((direction == GTK_DIR_UP) && (dist1 > 0)))
-       tmp_list->data = NULL;
+  return gtk_container_focus_move (container, *children, direction);
+}
 
-      tmp_list = tmp_list->next;
-    }
+static gint
+left_right_compare (gconstpointer a,
+                   gconstpointer b,
+                   gpointer      data)
+{
+  const GtkWidget *child1 = a;
+  const GtkWidget *child2 = b;
+  CompareInfo *compare = data;
 
-  if (direction == GTK_DIR_UP)
-    children = g_list_reverse (children);
+  gint x1 = child1->allocation.x + child1->allocation.width / 2;
+  gint x2 = child2->allocation.x + child2->allocation.width / 2;
 
-  return gtk_container_focus_move (container, children, direction);
+  if (x1 == x2)
+    {
+      gint y1 = abs (child1->allocation.y + child1->allocation.height / 2 - compare->y);
+      gint y2 = abs (child2->allocation.y + child2->allocation.height / 2 - compare->y);
+
+      if (compare->x < x1)
+       return (y1 < y2) ? -1 : ((y1 == y2) ? 0 : 1);
+      else
+       return (y1 < y2) ? 1 : ((y1 == y2) ? 0 : -1);
+    }
+  else
+    return (x1 < x2) ? -1 : 1;
 }
 
-static gint
+static gboolean
 gtk_container_focus_left_right (GtkContainer     *container,
-                               GList            *children,
+                               GList           **children,
                                GtkDirectionType  direction)
 {
-  GtkWidget *child;
-  GtkWidget *child2;
+  CompareInfo compare;
   GList *tmp_list;
-  gint dist1, dist2;
-  gint focus_y;
-  gint focus_height;
-  guint length;
-  guint i, j;
 
-  /* return failure if there isn't a focus child */
   if (container->focus_child)
     {
-      focus_height = container->focus_child->allocation.height / 2;
-      focus_y = container->focus_child->allocation.y + focus_height;
-    }
-  else
-    {
-      focus_height = GTK_WIDGET (container)->allocation.height;
-      if (GTK_WIDGET_NO_WINDOW (container))
-       focus_y = GTK_WIDGET (container)->allocation.y;
-      else
-       focus_y = 0;
-    }
+      gint compare_y1;
+      gint compare_y2;
+      gint compare_x;
+      
+      /* Delete widgets from list that don't match minimum criteria */
 
-  length = g_list_length (children);
+      compare_y1 = container->focus_child->allocation.y;
+      compare_y2 = container->focus_child->allocation.y + container->focus_child->allocation.height;
 
-  /* sort the children in the x direction */
-  for (i = 1; i < length; i++)
-    {
-      j = i;
-      tmp_list = g_list_nth (children, j);
-      child = tmp_list->data;
-
-      while (j > 0)
+      if (direction == GTK_DIR_LEFT)
+       compare_x = container->focus_child->allocation.x;
+      else
+       compare_x = container->focus_child->allocation.x + container->focus_child->allocation.width;
+      
+      tmp_list = *children;
+      while (tmp_list)
        {
-         child2 = tmp_list->prev->data;
-         if (child->allocation.x < child2->allocation.x)
+         GtkWidget *child = tmp_list->data;
+         GList *next = tmp_list->next;
+         gint child_y1, child_y2;
+         
+         if (child != container->focus_child)
            {
-             tmp_list->data = tmp_list->prev->data;
-             tmp_list = tmp_list->prev;
-             j--;
+             child_y1 = child->allocation.y;
+             child_y2 = child->allocation.y + child->allocation.height;
+             
+             if ((child_y2 <= compare_y1 || child_y1 >= compare_y2) /* No vertical overlap */ ||
+                 (direction == GTK_DIR_RIGHT && child->allocation.x + child->allocation.width < compare_x) || /* Not to left */
+                 (direction == GTK_DIR_LEFT && child->allocation.x > compare_x)) /* Not to right */
+               {
+                 *children = g_list_delete_link (*children, tmp_list);
+               }
            }
-         else
-           break;
+         
+         tmp_list = next;
        }
 
-      tmp_list->data = child;
+      compare.y = (compare_y1 + compare_y2) / 2;
+      compare.x = container->focus_child->allocation.x + container->focus_child->allocation.width / 2;
     }
-
-  /* sort the children in distance in the y direction
-   *  in distance from the current focus child while maintaining the
-   *  sort in the x direction
-   */
-  for (i = 1; i < length; i++)
+  else
     {
-      j = i;
-      tmp_list = g_list_nth (children, j);
-      child = tmp_list->data;
-      dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
+      /* No old focus widget, need to figure out starting x,y some other way
+       */
+      GtkWidget *widget = GTK_WIDGET (container);
+      GdkRectangle old_focus_rect;
 
-      while (j > 0)
+      if (old_focus_coords (container, &old_focus_rect))
        {
-         child2 = tmp_list->prev->data;
-         dist2 = (child2->allocation.y + child2->allocation.height / 2) - focus_y;
-
-         if ((dist1 < dist2) &&
-             (child->allocation.x >= child2->allocation.x))
-           {
-             tmp_list->data = tmp_list->prev->data;
-             tmp_list = tmp_list->prev;
-             j--;
-           }
+         compare.y = old_focus_rect.y + old_focus_rect.height / 2;
+       }
+      else
+       {
+         if (GTK_WIDGET_NO_WINDOW (widget))
+           compare.y = widget->allocation.y + widget->allocation.height / 2;
          else
-           break;
+           compare.y = widget->allocation.height / 2;
        }
-
-      tmp_list->data = child;
+      
+      if (GTK_WIDGET_NO_WINDOW (widget))
+       compare.x = (direction == GTK_DIR_RIGHT) ? widget->allocation.x : widget->allocation.x + widget->allocation.width;
+      else
+       compare.x = (direction == GTK_DIR_RIGHT) ? 0 : widget->allocation.width;
     }
 
-  /* go and invalidate any widget which is too
-   *  far from the focus widget.
-   */
-  if (!container->focus_child &&
-      (direction == GTK_DIR_LEFT))
-    focus_y += focus_height;
-
-  tmp_list = children;
-  while (tmp_list)
-    {
-      child = tmp_list->data;
-
-      dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
-      if (((direction == GTK_DIR_RIGHT) && (dist1 < 0)) ||
-         ((direction == GTK_DIR_LEFT) && (dist1 > 0)))
-       tmp_list->data = NULL;
-
-      tmp_list = tmp_list->next;
-    }
+  *children = g_list_sort_with_data (*children, left_right_compare, &compare);
 
   if (direction == GTK_DIR_LEFT)
-    children = g_list_reverse (children);
+    *children = g_list_reverse (*children);
 
-  return gtk_container_focus_move (container, children, direction);
+  return gtk_container_focus_move (container, *children, direction);
 }
 
-static gint
+static gboolean
 gtk_container_focus_move (GtkContainer     *container,
                          GList            *children,
                          GtkDirectionType  direction)
@@ -1722,7 +1786,6 @@ gtk_container_focus_move (GtkContainer     *container,
   GtkWidget *child;
 
   focus_child = container->focus_child;
-  gtk_container_set_focus_child (container, NULL);
 
   while (children)
     {
@@ -1739,8 +1802,7 @@ gtk_container_focus_move (GtkContainer     *container,
               focus_child = NULL;
 
               if (GTK_WIDGET_DRAWABLE (child) &&
-                 GTK_IS_CONTAINER (child) &&
-                 !GTK_WIDGET_HAS_FOCUS (child))
+                 GTK_IS_CONTAINER (child))
                if (gtk_container_focus (GTK_CONTAINER (child), direction))
                  return TRUE;
             }
index 93c29c0428f8661a0b5e2a4011d0019273791999..0da0c11845a6fc5176bb316c9b6bd8128621d3a6 100644 (file)
@@ -83,7 +83,7 @@ struct _GtkContainerClass
                                 gboolean         include_internals,
                                 GtkCallback      callback,
                                 gpointer         callbabck_data);
-  gint (* focus)                       (GtkContainer    *container,
+  gboolean (* focus)                   (GtkContainer    *container,
                                 GtkDirectionType  direction);
   void (* set_focus_child)     (GtkContainer    *container,
                                 GtkWidget       *widget);
@@ -119,17 +119,17 @@ void    gtk_container_set_resize_mode    (GtkContainer     *container,
 
 void    gtk_container_check_resize       (GtkContainer     *container);
 
-void    gtk_container_foreach           (GtkContainer     *container,
-                                         GtkCallback       callback,
-                                         gpointer          callback_data);
-void    gtk_container_foreach_full      (GtkContainer     *container,
-                                         GtkCallback       callback,
-                                         GtkCallbackMarshal marshal,
-                                         gpointer          callback_data,
-                                         GtkDestroyNotify  notify);
-GList* gtk_container_children           (GtkContainer     *container);
-gint   gtk_container_focus                (GtkContainer     *container,
-                                           GtkDirectionType  direction);
+void     gtk_container_foreach      (GtkContainer       *container,
+                                    GtkCallback         callback,
+                                    gpointer            callback_data);
+void     gtk_container_foreach_full (GtkContainer       *container,
+                                    GtkCallback         callback,
+                                    GtkCallbackMarshal  marshal,
+                                    gpointer            callback_data,
+                                    GtkDestroyNotify    notify);
+GList*   gtk_container_children     (GtkContainer       *container);
+gboolean gtk_container_focus        (GtkContainer       *container,
+                                    GtkDirectionType    direction);
 
 /* Widget-level methods */
 
index 73f5a352910f393851e3fa92c7f05ffbd71ef5e0..424fd869da2a5389b34fa7a1274f42109ab18932 100644 (file)
@@ -78,6 +78,33 @@ enum {
   CHILD_ARG_TAB_PACK
 };
 
+#define GTK_NOTEBOOK_PAGE(_glist_)         ((GtkNotebookPage *)((GList *)(_glist_))->data)
+
+struct _GtkNotebookPage
+{
+  GtkWidget *child;
+  GtkWidget *tab_label;
+  GtkWidget *menu_label;
+
+  guint default_menu : 1;      /* If true, we create the menu label ourself */
+  guint default_tab  : 1;      /* If true, we create the tab label ourself */
+  guint expand       : 1;
+  guint fill         : 1;
+  guint pack         : 1;
+
+  GtkRequisition requisition;
+  GtkAllocation allocation;
+};
+
+#ifdef G_DISABLE_CHECKS
+#define CHECK_FIND_CHILD(notebook, child)                           \
+ gtk_notebook_find_child(notebook, child,                           \
+                        G_GNUC_PRETTY_FUNCTION)
+#else
+#define CHECK_FIND_CHILD(notebook, child)                           \
+ gtk_notebook_find_child(notebook, child, NULL)
+#endif
 /*** GtkNotebook Methods ***/
 static void gtk_notebook_class_init          (GtkNotebookClass *klass);
 static void gtk_notebook_init                (GtkNotebook      *notebook);
@@ -147,7 +174,8 @@ static void gtk_notebook_forall              (GtkContainer     *container,
 
 /*** GtkNotebook Private Functions ***/
 static void gtk_notebook_panel_realize       (GtkNotebook      *notebook);
-static void gtk_notebook_expose_tabs         (GtkNotebook      *notebook);
+static void gtk_notebook_redraw_tabs         (GtkNotebook      *notebook);
+static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
 static void gtk_notebook_focus_changed       (GtkNotebook      *notebook,
                                              GtkNotebookPage  *old_page);
 static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
@@ -156,6 +184,9 @@ static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
 static gint gtk_notebook_timer               (GtkNotebook      *notebook);
 static gint gtk_notebook_page_compare        (gconstpointer     a,
                                              gconstpointer     b);
+static GList *gtk_notebook_find_child        (GtkNotebook      *notebook,
+                                             GtkWidget        *child,
+                                             const gchar      *function);
 static gint  gtk_notebook_real_page_position (GtkNotebook      *notebook,
                                              GList            *list);
 static GList * gtk_notebook_search_page      (GtkNotebook      *notebook,
@@ -174,8 +205,7 @@ static void gtk_notebook_draw_arrow          (GtkNotebook      *notebook,
 static void gtk_notebook_set_shape           (GtkNotebook      *notebook);
 
 /*** GtkNotebook Size Allocate Functions ***/
-static void gtk_notebook_pages_allocate      (GtkNotebook      *notebook,
-                                             GtkAllocation    *allocation);
+static void gtk_notebook_pages_allocate      (GtkNotebook      *notebook);
 static void gtk_notebook_page_allocate       (GtkNotebook      *notebook,
                                              GtkNotebookPage  *page,
                                              GtkAllocation    *allocation);
@@ -194,7 +224,8 @@ static void gtk_notebook_real_switch_page    (GtkNotebook      *notebook,
 static void gtk_notebook_switch_page         (GtkNotebook      *notebook,
                                              GtkNotebookPage  *page,
                                              gint              page_num);
-static gint gtk_notebook_page_select         (GtkNotebook      *notebook);
+static gint gtk_notebook_page_select         (GtkNotebook      *notebook,
+                                             gboolean          move_focus);
 static void gtk_notebook_switch_focus_tab    (GtkNotebook      *notebook,
                                               GList            *new_child);
 static void gtk_notebook_menu_switch_page    (GtkWidget        *widget,
@@ -315,7 +346,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
 static void
 gtk_notebook_init (GtkNotebook *notebook)
 {
-  GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS);
+  GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT);
   GTK_WIDGET_UNSET_FLAGS (notebook, GTK_NO_WINDOW);
 
   notebook->cur_page = NULL;
@@ -340,6 +371,14 @@ gtk_notebook_init (GtkNotebook *notebook)
   notebook->have_visible_child = FALSE;
 }
 
+/**
+ * gtk_notebook_new:
+ * @void: 
+ * 
+ * Creates a new #GtkNotebook widget with no pages.
+
+ * Return value: the newly created #GtkNotebook
+ **/
 GtkWidget*
 gtk_notebook_new (void)
 {
@@ -500,7 +539,7 @@ gtk_notebook_map (GtkWidget *widget)
     gtk_widget_map (notebook->cur_page->child);
 
   if (notebook->scrollable)
-      gtk_notebook_pages_allocate (notebook, &(widget->allocation));
+    gtk_notebook_pages_allocate (notebook);
   else
     {
       children = notebook->children;
@@ -915,7 +954,7 @@ gtk_notebook_size_allocate (GtkWidget     *widget,
            gtk_widget_size_allocate (page->child, &child_allocation);
        }
 
-      gtk_notebook_pages_allocate (notebook, allocation);
+      gtk_notebook_pages_allocate (notebook);
     }
    gtk_notebook_set_shape (notebook);
 }
@@ -956,7 +995,51 @@ gtk_notebook_expose (GtkWidget      *widget,
   return FALSE;
 }
 
-static gint
+static gboolean
+gtk_notebook_arrow_button_press (GtkNotebook    *notebook,
+                                GdkEventButton *event)
+{
+  GtkWidget *widget = GTK_WIDGET (notebook);
+  
+  GtkArrowType arrow = event->x <= ARROW_SIZE + ARROW_SPACING / 2 ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT;
+
+  if (!GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_widget_grab_focus (widget);
+  
+  notebook->button = event->button;
+  notebook->click_child = arrow;
+  
+  if (event->button == 1)
+    {
+      if (!notebook->focus_tab ||
+         gtk_notebook_search_page (notebook, notebook->focus_tab,
+                                   arrow == GTK_ARROW_LEFT ? STEP_PREV : STEP_NEXT,
+                                   TRUE))
+       gtk_container_focus (GTK_CONTAINER (notebook),
+                            arrow == GTK_ARROW_LEFT ? GTK_DIR_LEFT : GTK_DIR_RIGHT);
+      
+      if (!notebook->timer)
+       {
+         notebook->timer = gtk_timeout_add 
+           (NOTEBOOK_INIT_SCROLL_DELAY, 
+            (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
+         notebook->need_timer = TRUE;
+       }
+    }
+  else if (event->button == 2)
+    gtk_notebook_page_select (notebook, TRUE);
+  else if (event->button == 3)
+    gtk_notebook_switch_focus_tab (notebook,
+                                  gtk_notebook_search_page (notebook,
+                                                            NULL,
+                                                            arrow == GTK_ARROW_LEFT ? STEP_NEXT : STEP_PREV,
+                                                            TRUE));
+  gtk_notebook_redraw_arrows (notebook);
+
+  return TRUE;
+}
+
+static gboolean
 gtk_notebook_button_press (GtkWidget      *widget,
                           GdkEventButton *event)
 {
@@ -977,66 +1060,7 @@ gtk_notebook_button_press (GtkWidget      *widget,
 
   if (event->window == notebook->panel)
     {
-      if (!GTK_WIDGET_HAS_FOCUS (widget))
-       gtk_widget_grab_focus (widget);
-
-      gtk_grab_add (widget);
-      notebook->button = event->button;
-
-      if (event->x <= ARROW_SIZE + ARROW_SPACING / 2)
-       {
-         notebook->click_child = GTK_ARROW_LEFT;
-         if (event->button == 1)
-           {
-             if (!notebook->focus_tab ||
-                 gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                           STEP_PREV, TRUE))
-               gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT);
-
-             if (!notebook->timer)
-               {
-                 notebook->timer = gtk_timeout_add 
-                   (NOTEBOOK_INIT_SCROLL_DELAY, 
-                    (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
-                 notebook->need_timer = TRUE;
-               }
-           }
-         else if (event->button == 2)
-           gtk_notebook_page_select (GTK_NOTEBOOK (widget));
-         else if (event->button == 3)
-           gtk_notebook_switch_focus_tab (notebook,
-                                          gtk_notebook_search_page (notebook,
-                                                                    NULL,
-                                                                    STEP_NEXT,
-                                                                    TRUE));
-         gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
-       }
-      else
-       {
-         notebook->click_child = GTK_ARROW_RIGHT;
-         if (event->button == 1)
-           {
-             if (!notebook->focus_tab ||
-                 gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                           STEP_NEXT, TRUE))
-               gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT);
-
-             if (!notebook->timer)
-               {
-                 notebook->timer = gtk_timeout_add 
-                   (NOTEBOOK_INIT_SCROLL_DELAY, 
-                    (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
-                 notebook->need_timer = TRUE;
-               }
-           }      
-         else if (event->button == 2)
-           gtk_notebook_page_select (GTK_NOTEBOOK (widget));
-         else if (event->button == 3)
-           gtk_notebook_switch_focus_tab
-             (notebook, gtk_notebook_search_page (notebook, NULL,
-                                                  STEP_PREV, TRUE));
-         gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
-       }
+      return gtk_notebook_arrow_button_press (notebook, event);
     }
   else if (event->window == widget->window)
     {
@@ -1044,7 +1068,7 @@ gtk_notebook_button_press (GtkWidget      *widget,
        {
          gtk_menu_popup (GTK_MENU (notebook->menu), NULL, NULL, 
                          NULL, NULL, 3, event->time);
-         return FALSE;
+         return TRUE;
        }
 
       num = 0;
@@ -1086,8 +1110,8 @@ gtk_notebook_button_press (GtkWidget      *widget,
       if (!children && !GTK_WIDGET_HAS_FOCUS (widget))
        gtk_widget_grab_focus (widget);
     }
-   gtk_notebook_set_shape (notebook);
-  return FALSE;
+   
+  return TRUE;
 }
 
 static gint
@@ -1115,11 +1139,10 @@ gtk_notebook_button_release (GtkWidget      *widget,
          notebook->timer = 0;
          notebook->need_timer = FALSE;
        }
-      gtk_grab_remove (widget);
       click_child = notebook->click_child;
       notebook->click_child = 0;
       notebook->button = 0;
-      gtk_notebook_draw_arrow (notebook, click_child);
+      gtk_notebook_redraw_arrows (notebook);
       
     }
   return FALSE;
@@ -1145,19 +1168,11 @@ gtk_notebook_enter_notify (GtkWidget        *widget,
       gdk_window_get_pointer (notebook->panel, &x, &y, NULL);
 
       if (x <= ARROW_SIZE + ARROW_SPACING / 2)
-       {
-         notebook->in_child = GTK_ARROW_LEFT;
-
-         if (notebook->click_child == 0) 
-           gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
-       }
-      else 
-       {
-         notebook->in_child = GTK_ARROW_RIGHT;
+       notebook->in_child = GTK_ARROW_LEFT;
+      else
+       notebook->in_child = GTK_ARROW_RIGHT;
 
-         if (notebook->click_child == 0) 
-           gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
-       }
+      gtk_notebook_redraw_arrows (notebook);
     }
 
   return FALSE;
@@ -1175,19 +1190,9 @@ gtk_notebook_leave_notify (GtkWidget        *widget,
 
   notebook = GTK_NOTEBOOK (widget);
 
-  if (event->window == notebook->panel && !notebook->click_child)
-    {
-      if (notebook->in_child == GTK_ARROW_LEFT)
-       {
-          notebook->in_child = 0;
-         gtk_notebook_draw_arrow (notebook,GTK_ARROW_LEFT);
-       }
-      else
-       {
-          notebook->in_child = 0;
-         gtk_notebook_draw_arrow (notebook,GTK_ARROW_RIGHT);
-       }
-    }
+  if (event->window == notebook->panel)
+    gtk_notebook_redraw_arrows (notebook);
+
   return FALSE;
 }
 
@@ -1209,27 +1214,21 @@ gtk_notebook_motion_notify (GtkWidget      *widget,
   if (event->window == notebook->panel)
     {
       gint x;
+      GtkArrowType old_child = notebook->in_child;
       
       x = event->x;
       if (event->is_hint)
         gdk_window_get_pointer (notebook->panel, &x, NULL, NULL);
 
-      if (x <= ARROW_SIZE + ARROW_SPACING / 2 && 
-          notebook->in_child == GTK_ARROW_RIGHT)
-        {
-          notebook->in_child = GTK_ARROW_LEFT;
-          gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
-          gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
-        }
-      else if (x > ARROW_SIZE + ARROW_SPACING / 2 && 
-              notebook->in_child == GTK_ARROW_LEFT)
-        {
-          notebook->in_child = GTK_ARROW_RIGHT;
-          gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
-          gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
-        }
-      return FALSE;
+      if (x <= ARROW_SIZE + ARROW_SPACING / 2)
+       notebook->in_child = GTK_ARROW_LEFT;
+      else
+       notebook->in_child = GTK_ARROW_RIGHT;
+
+      if (old_child != notebook->in_child)
+       gtk_notebook_redraw_arrows (notebook);  
     }
+  
   return FALSE;
 }
 
@@ -1238,7 +1237,6 @@ gtk_notebook_key_press (GtkWidget   *widget,
                        GdkEventKey *event)
 {
   GtkNotebook *notebook;
-  GtkDirectionType direction = 0;
   GList *list;
 
   g_return_val_if_fail (widget != NULL, FALSE);
@@ -1252,65 +1250,6 @@ gtk_notebook_key_press (GtkWidget   *widget,
 
   switch (event->keyval)
     {
-    case GDK_Up:
-      switch (notebook->tab_pos)
-       {
-       case GTK_POS_BOTTOM:
-         gtk_notebook_page_select (GTK_NOTEBOOK (widget));
-         return TRUE;
-       case GTK_POS_TOP:
-         return FALSE;
-       default:
-         direction = GTK_DIR_UP;
-         break;
-       }
-      break;
-    case GDK_Left:
-      switch (notebook->tab_pos)
-       {
-       case GTK_POS_RIGHT:
-         gtk_notebook_page_select (GTK_NOTEBOOK (widget));
-         return TRUE;
-       case GTK_POS_LEFT:
-         return FALSE;
-       default:
-         direction = GTK_DIR_LEFT;
-         break;
-       }
-      break;
-    case GDK_Down:
-      switch (notebook->tab_pos)
-       {
-       case GTK_POS_TOP:
-         gtk_notebook_page_select (GTK_NOTEBOOK (widget));
-         return TRUE;
-       case GTK_POS_BOTTOM:
-         return FALSE;
-       default:
-         direction = GTK_DIR_DOWN;
-         break;
-       }
-      break;
-    case GDK_Right:
-      switch (notebook->tab_pos)
-       {
-       case GTK_POS_LEFT:
-         gtk_notebook_page_select (GTK_NOTEBOOK (widget));
-         return TRUE;
-       case GTK_POS_RIGHT:
-         return FALSE;
-       default:
-         direction = GTK_DIR_RIGHT;
-         break;
-       }
-      break;
-    case GDK_Tab:
-    case GDK_ISO_Left_Tab:
-      if (event->state & GDK_SHIFT_MASK)
-       direction = GTK_DIR_TAB_BACKWARD;
-      else
-       direction = GTK_DIR_TAB_FORWARD;
-      break;
     case GDK_Home:
       list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
       if (list)
@@ -1322,13 +1261,14 @@ gtk_notebook_key_press (GtkWidget   *widget,
        gtk_notebook_switch_focus_tab (notebook, list);
       return TRUE;
     case GDK_Return:
+      gtk_notebook_page_select (GTK_NOTEBOOK (widget), TRUE);
+      return TRUE;
     case GDK_space:
-      gtk_notebook_page_select (GTK_NOTEBOOK (widget));
+      gtk_notebook_page_select (GTK_NOTEBOOK (widget), FALSE);
       return TRUE;
-    default:
-      return FALSE;
     }
-  return gtk_container_focus (GTK_CONTAINER (widget), direction);
+
+  return FALSE;
 }
 
 static gint
@@ -1482,8 +1422,10 @@ gtk_notebook_get_child_arg (GtkContainer     *container,
 
   notebook = GTK_NOTEBOOK (container);
 
-  if (!(list = g_list_find_custom (notebook->children, child,
-                                  gtk_notebook_page_compare)))
+  arg->type = GTK_TYPE_INVALID;
+  
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)  
     {
       arg->type = GTK_TYPE_INVALID;
       return;
@@ -1572,112 +1514,169 @@ gtk_notebook_remove (GtkContainer *container,
     }
 }
 
+static gboolean
+focus_tabs_in (GtkNotebook *notebook)
+{
+  if (notebook->cur_page)
+    {
+      gtk_widget_grab_focus (GTK_WIDGET (notebook));
+
+      gtk_notebook_switch_focus_tab (notebook,
+                                    g_list_find (notebook->children,
+                                                 notebook->cur_page));
+
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+static gboolean
+focus_tabs_move (GtkNotebook     *notebook,
+                GtkDirectionType direction,
+                gint             search_direction)
+{
+  GList *new_page;
+
+  new_page = gtk_notebook_search_page (notebook, notebook->focus_tab,
+                                      search_direction, TRUE);
+  if (!new_page)
+    new_page = (search_direction == STEP_NEXT) ?
+                 notebook->children :
+                 g_list_last (notebook->children);
+
+  gtk_notebook_switch_focus_tab (notebook, new_page);
+  
+  return TRUE;
+}
+
+static gboolean
+focus_child_in (GtkNotebook     *notebook,
+               GtkDirectionType direction)
+{
+  if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) &&
+      GTK_WIDGET_IS_SENSITIVE (notebook->cur_page->child))
+    {
+      if (GTK_IS_CONTAINER (notebook->cur_page->child))
+       {
+         if (gtk_container_focus (GTK_CONTAINER (notebook->cur_page->child), direction))
+           return TRUE;
+       }
+      else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child))
+       {
+         gtk_widget_grab_focus (notebook->cur_page->child);
+         return TRUE;
+       }
+    }
+  return FALSE;
+}
+
+/* Focus in the notebook can either be on the pages, or on
+ * the tabs.
+ */
 static gint
 gtk_notebook_focus (GtkContainer     *container,
                    GtkDirectionType  direction)
 {
+  GtkWidget *old_focus_child;
   GtkNotebook *notebook;
-  GtkNotebookPage *page = NULL;
-  GtkNotebookPage *old_page = NULL;
+  GtkDirectionType effective_direction;
+
+  /* Remap the directions into the effective direction it would be for a
+   * GTK_POS_TOP notebook
+   */
+#define D(rest) GTK_DIR_##rest
+
+  static const GtkDirectionType translate_direction[4][6] = {
+    /* LEFT */   { D(TAB_FORWARD),  D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP),   D(DOWN) },
+    /* RIGHT */  { D(TAB_BACKWARD), D(TAB_FORWARD),  D(LEFT), D(RIGHT), D(DOWN), D(UP)   },
+    /* TOP */    { D(TAB_FORWARD),  D(TAB_BACKWARD), D(UP),   D(DOWN),  D(LEFT), D(RIGHT) },
+    /* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD),  D(DOWN), D(UP),    D(LEFT), D(RIGHT) },
+  };
+
+#undef D  
+
+  gboolean widget_is_focus;
 
   g_return_val_if_fail (container != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_NOTEBOOK (container), FALSE);
 
   notebook = GTK_NOTEBOOK (container);
 
-  if (!GTK_WIDGET_DRAWABLE (notebook) ||
-      !GTK_WIDGET_IS_SENSITIVE (container) ||
-      !notebook->children ||
-      !notebook->cur_page)
-    return FALSE;
+  widget_is_focus = gtk_widget_is_focus (GTK_WIDGET (container));
+  old_focus_child = container->focus_child; 
 
-  if (!notebook->show_tabs)
-    {
-      if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) &&
-         GTK_WIDGET_IS_SENSITIVE (notebook->cur_page->child))
-       {
-         if (GTK_IS_CONTAINER (notebook->cur_page->child))
-           {
-             if (gtk_container_focus
-                 (GTK_CONTAINER (notebook->cur_page->child), direction))
-               return TRUE;
-           }
-         else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child))
-           {
-             if (!container->focus_child)
-               {
-                 gtk_widget_grab_focus (notebook->cur_page->child);
-                 return TRUE;
-               }
-           }
-       }
-      return FALSE;
-    }
+  effective_direction = translate_direction[notebook->tab_pos][direction];
 
-  if (notebook->focus_tab)
-    old_page = notebook->focus_tab->data;
+  if (old_focus_child &&
+      GTK_IS_CONTAINER (old_focus_child) &&
+      GTK_WIDGET_DRAWABLE (old_focus_child) &&
+      GTK_WIDGET_IS_SENSITIVE (old_focus_child) &&
+      gtk_container_focus (GTK_CONTAINER (old_focus_child), direction))
+    return TRUE;
 
-  if (container->focus_child && old_page &&
-      container->focus_child == old_page->child && notebook->child_has_focus)
+  if (old_focus_child)         /* Focus on page child */
     {
-      if (GTK_WIDGET_DRAWABLE (container->focus_child))
+      switch (effective_direction)
        {
-         if (GTK_IS_CONTAINER (container->focus_child) &&
-             !GTK_WIDGET_HAS_FOCUS (container->focus_child))
-           {
-             if (gtk_container_focus (GTK_CONTAINER (container->focus_child),
-                                      direction))
-               return TRUE;
-           }
-         gtk_widget_grab_focus (GTK_WIDGET(notebook));
-         return TRUE;
+       case GTK_DIR_TAB_BACKWARD:
+       case GTK_DIR_UP:
+         /* Focus onto the tabs */
+         if (notebook->show_tabs)
+           return focus_tabs_in (notebook);
+         else
+           return FALSE;
+       case GTK_DIR_DOWN:
+       case GTK_DIR_TAB_FORWARD:
+       case GTK_DIR_LEFT:
+       case GTK_DIR_RIGHT:
+         return FALSE;
        }
-      notebook->focus_tab = NULL;
-      return FALSE;
     }
-
-  if (!GTK_WIDGET_HAS_FOCUS (container))
-    notebook->focus_tab = NULL;
-
-  switch (direction)
+  else if (widget_is_focus)    /* Focus was on tabs */
     {
-    case GTK_DIR_TAB_FORWARD:
-    case GTK_DIR_RIGHT:
-    case GTK_DIR_DOWN:
-      gtk_notebook_switch_focus_tab
-       (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                            STEP_NEXT, TRUE));
-      break;
-    case GTK_DIR_TAB_BACKWARD:
-    case GTK_DIR_LEFT:
-    case GTK_DIR_UP:
-      gtk_notebook_switch_focus_tab
-       (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                            STEP_PREV, TRUE));
-      break;
+      switch (effective_direction)
+       {
+       case GTK_DIR_TAB_BACKWARD:
+       case GTK_DIR_UP:
+         return FALSE;
+       case GTK_DIR_TAB_FORWARD:
+       case GTK_DIR_DOWN:
+         return focus_child_in (notebook, direction);
+       case GTK_DIR_LEFT:
+         return focus_tabs_move (notebook, direction, STEP_PREV);
+       case GTK_DIR_RIGHT:
+         return focus_tabs_move (notebook, direction, STEP_NEXT);
+       }
     }
-
-  if (notebook->focus_tab)
+  else /* Focus was not on widget */
     {
-      if (!GTK_WIDGET_HAS_FOCUS (container))
-       gtk_widget_grab_focus (GTK_WIDGET (container));
-
-      page = notebook->focus_tab->data;
-      if (GTK_WIDGET_MAPPED (page->tab_label))
-       gtk_notebook_focus_changed (notebook, old_page);
-      else
+      switch (effective_direction)
        {
-         gtk_notebook_pages_allocate (notebook, 
-                                      &(GTK_WIDGET (notebook)->allocation));
-         gtk_notebook_expose_tabs (notebook);
+       case GTK_DIR_TAB_FORWARD:
+       case GTK_DIR_DOWN:
+         if (focus_tabs_in (notebook))
+           return TRUE;
+         if (focus_child_in (notebook, direction))
+           return TRUE;
+         return FALSE;
+       case GTK_DIR_TAB_BACKWARD:
+       case GTK_DIR_UP:
+         if (focus_child_in (notebook, direction))
+           return TRUE;
+         if (focus_tabs_in (notebook))
+           return TRUE;
+         return FALSE;
+       case GTK_DIR_LEFT:
+       case GTK_DIR_RIGHT:
+         return focus_child_in (notebook, direction);
        }
-      return TRUE;
     }
 
-  gtk_notebook_focus_changed (notebook, old_page);
+  g_assert_not_reached ();
   return FALSE;
-}
-
+}  
+  
 static void
 gtk_notebook_set_focus_child (GtkContainer *container,
                              GtkWidget    *child)
@@ -1754,7 +1753,7 @@ gtk_notebook_child_type (GtkContainer     *container)
 /* Private GtkNotebook Functions:
  *
  * gtk_notebook_panel_realize
- * gtk_notebook_expose_tabs
+ * gtk_notebook_redraw_tabs
  * gtk_notebook_focus_changed
  * gtk_notebook_real_remove
  * gtk_notebook_update_labels
@@ -1808,11 +1807,11 @@ gtk_notebook_panel_realize (GtkNotebook *notebook)
 }
 
 static void
-gtk_notebook_expose_tabs (GtkNotebook *notebook)
+gtk_notebook_redraw_tabs (GtkNotebook *notebook)
 {
   GtkWidget *widget;
   GtkNotebookPage *page;
-  GdkEventExpose event;
+  GdkRectangle redraw_rect;
   gint border;
 
   widget = GTK_WIDGET (notebook);
@@ -1823,42 +1822,49 @@ gtk_notebook_expose_tabs (GtkNotebook *notebook)
 
   page = notebook->first_tab->data;
 
-  event.type = GDK_EXPOSE;
-  event.window = widget->window;
-  event.count = 0;
-  event.area.x = border;
-  event.area.y = border;
+  redraw_rect.x = border;
+  redraw_rect.y = border;
 
   switch (notebook->tab_pos)
     {
     case GTK_POS_BOTTOM:
-      event.area.y = (widget->allocation.height - border -
-                     page->allocation.height -
-                     widget->style->ythickness);
+      redraw_rect.y = (widget->allocation.height - border -
+                      page->allocation.height -
+                      widget->style->ythickness);
       if (page != notebook->cur_page)
-       event.area.y -= widget->style->ythickness;
+       redraw_rect.y -= widget->style->ythickness;
+      /* fall through */
     case GTK_POS_TOP:
-      event.area.width = widget->allocation.width - 2 * border;
-      event.area.height = (page->allocation.height +
-                          widget->style->ythickness);
+      redraw_rect.width = widget->allocation.width - 2 * border;
+      redraw_rect.height = (page->allocation.height +
+                           widget->style->ythickness);
       if (page != notebook->cur_page)
-       event.area.height += widget->style->ythickness;
+       redraw_rect.height += widget->style->ythickness;
       break;
     case GTK_POS_RIGHT:
-      event.area.x = (widget->allocation.width - border -
-                     page->allocation.width -
-                     widget->style->xthickness);
+      redraw_rect.x = (widget->allocation.width - border -
+                      page->allocation.width -
+                      widget->style->xthickness);
       if (page != notebook->cur_page)
-       event.area.x -= widget->style->xthickness;
+       redraw_rect.x -= widget->style->xthickness;
+      /* fall through */
     case GTK_POS_LEFT:
-      event.area.width = (page->allocation.width +
-                         widget->style->xthickness);
-      event.area.height = widget->allocation.height - 2 * border;
+      redraw_rect.width = (page->allocation.width +
+                          widget->style->xthickness);
+      redraw_rect.height = widget->allocation.height - 2 * border;
       if (page != notebook->cur_page)
-       event.area.width += widget->style->xthickness;
+       redraw_rect.width += widget->style->xthickness;
       break;
-    }       
-  gtk_widget_event (widget, (GdkEvent *) &event);
+    }
+
+  gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
+}
+
+static void
+gtk_notebook_redraw_arrows (GtkNotebook *notebook)
+{
+  if (GTK_WIDGET_MAPPED (notebook) && notebook->panel)
+    gdk_window_invalidate_rect (notebook->panel, NULL, FALSE);
 }
 
 static void
@@ -1944,6 +1950,23 @@ gtk_notebook_page_compare (gconstpointer a,
   return (((GtkNotebookPage *) a)->child != b);
 }
 
+static GList *
+gtk_notebook_find_child (GtkNotebook      *notebook,
+                        GtkWidget        *child,
+                        const gchar      *function)
+{
+  GList *list = g_list_find_custom (notebook->children, child,
+                                   gtk_notebook_page_compare);
+
+#ifndef G_DISABLE_CHECKS
+  if (!list)
+    g_warning ("child argument to '%s' does not refer to the contents of a notebook page",
+              function);
+#endif
+
+  return list;
+}
+
 static void
 gtk_notebook_real_remove (GtkNotebook *notebook,
                          GList       *list)
@@ -2565,12 +2588,12 @@ gtk_notebook_set_shape (GtkNotebook *notebook)
  * gtk_notebook_calc_tabs
  */
 static void
-gtk_notebook_pages_allocate (GtkNotebook   *notebook,
-                            GtkAllocation *allocation)
+gtk_notebook_pages_allocate (GtkNotebook   *notebook)
 {
-  GtkWidget    *widget;
-  GtkContainer *container;
+  GtkWidget    *widget = GTK_WIDGET (notebook);
+  GtkContainer *container = GTK_CONTAINER (notebook);
   GtkNotebookPage *page = NULL;
+  GtkAllocation *allocation = &widget->allocation;
   GtkAllocation child_allocation;
   GList *children = NULL;
   GList *last_child = NULL;
@@ -2587,9 +2610,6 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook,
   if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
     return;
 
-  widget = GTK_WIDGET (notebook);
-  container = GTK_CONTAINER (notebook);
-
   child_allocation.x = container->border_width;
   child_allocation.y = container->border_width;
 
@@ -2599,13 +2619,16 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook,
       child_allocation.y = (allocation->height -
                            notebook->cur_page->requisition.height -
                            container->border_width);
+      /* fall through */
     case GTK_POS_TOP:
       child_allocation.height = notebook->cur_page->requisition.height;
       break;
+      
     case GTK_POS_RIGHT:
       child_allocation.x = (allocation->width -
                            notebook->cur_page->requisition.width -
                            container->border_width);
+      /* fall through */
     case GTK_POS_LEFT:
       child_allocation.width = notebook->cur_page->requisition.width;
       break;
@@ -2877,10 +2900,8 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook,
     {
       if (children == last_child)
        {
-         gtk_notebook_set_shape (notebook);
-         return;
-         children = NULL;
-         break;
+         /* FIXME double check */
+         goto done;
        }
 
       page = children->data;
@@ -3007,7 +3028,10 @@ gtk_notebook_pages_allocate (GtkNotebook   *notebook,
            }
        }
     }
+
+ done:
   gtk_notebook_set_shape (notebook);
+  gtk_notebook_redraw_tabs (notebook);  
 }
 
 static void
@@ -3305,9 +3329,11 @@ gtk_notebook_switch_page (GtkNotebook     *notebook,
 }
 
 static gint
-gtk_notebook_page_select (GtkNotebook *notebook)
+gtk_notebook_page_select (GtkNotebook *notebook,
+                         gboolean     move_focus)
 {
   GtkNotebookPage *page;
+  GtkDirectionType dir = GTK_DIR_DOWN; /* Quiet GCC */
 
   g_return_val_if_fail (notebook != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
@@ -3318,18 +3344,37 @@ gtk_notebook_page_select (GtkNotebook *notebook)
   page = notebook->focus_tab->data;
   gtk_notebook_switch_page (notebook, page, -1);
 
-  if (GTK_WIDGET_VISIBLE (page->child))
+  if (move_focus)
     {
-      if (GTK_IS_CONTAINER (page->child))
+      switch (notebook->tab_pos)
        {
-         if (gtk_container_focus (GTK_CONTAINER (page->child), 
-                                  GTK_DIR_TAB_FORWARD))
-           return TRUE;
+       case GTK_POS_TOP:
+         dir = GTK_DIR_DOWN;
+         break;
+       case GTK_POS_BOTTOM:
+         dir = GTK_DIR_UP;
+         break;
+       case GTK_POS_LEFT:
+         dir = GTK_DIR_RIGHT;
+         break;
+       case GTK_POS_RIGHT:
+         dir = GTK_DIR_LEFT;
+         break;
        }
-      else if (GTK_WIDGET_CAN_FOCUS (page->child))
+      
+      if (GTK_WIDGET_VISIBLE (page->child))
        {
-         gtk_widget_grab_focus (page->child);
-         return TRUE;
+         if (GTK_IS_CONTAINER (page->child))
+           {
+             if (gtk_container_focus (GTK_CONTAINER (page->child), 
+                                      dir))
+               return TRUE;
+           }
+         else if (GTK_WIDGET_CAN_FOCUS (page->child))
+           {
+             gtk_widget_grab_focus (page->child);
+             return TRUE;
+           }
        }
     }
   return FALSE;
@@ -3353,44 +3398,7 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
   notebook->focus_tab = new_child;
 
   if (notebook->scrollable && GTK_WIDGET_DRAWABLE (notebook))
-    {
-      if ((new_child == NULL) != (old_child == NULL))
-       {
-         gdk_window_clear (notebook->panel);
-         gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
-         gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
-       }
-      else
-       {
-         GList *olist;
-         GList *nlist;
-
-         olist = gtk_notebook_search_page (notebook, old_child,
-                                           STEP_PREV, TRUE);
-         nlist = gtk_notebook_search_page (notebook, new_child,
-                                           STEP_PREV, TRUE);
-
-         if ((olist == NULL) != (nlist == NULL))
-           {
-             gdk_window_clear_area (notebook->panel, 0, 0,
-                                    ARROW_SIZE, ARROW_SIZE);
-             gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
-           }
-
-         olist = gtk_notebook_search_page (notebook, old_child,
-                                           STEP_NEXT, TRUE);
-         nlist = gtk_notebook_search_page (notebook, new_child,
-                                           STEP_NEXT, TRUE);
-
-         if ((olist == NULL) != (nlist == NULL))
-           {
-             gdk_window_clear_area (notebook->panel,
-                                    ARROW_SIZE + ARROW_SPACING, 0,
-                                    ARROW_SIZE, ARROW_SIZE);
-             gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
-           }
-       }
-    }
+    gtk_notebook_redraw_arrows (notebook);
 
   if (!notebook->show_tabs || !notebook->focus_tab)
     return;
@@ -3402,11 +3410,7 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
   if (GTK_WIDGET_MAPPED (page->tab_label))
     gtk_notebook_focus_changed (notebook, old_page);
   else
-    {
-      gtk_notebook_pages_allocate (notebook,
-                                  &(GTK_WIDGET (notebook)->allocation));
-      gtk_notebook_expose_tabs (notebook);
-    }
+    gtk_notebook_pages_allocate (notebook);
 
   gtk_notebook_set_shape (notebook);
 }
@@ -3510,49 +3514,150 @@ gtk_notebook_menu_detacher (GtkWidget *widget,
  * gtk_notebook_insert_page_menu
  * gtk_notebook_remove_page
  */
+/**
+ * gtk_notebook_append_page:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ *             or %NULL to use the default label, 'page N'.
+ * 
+ * Appends a page to @notebook.
+ **/
 void
 gtk_notebook_append_page (GtkNotebook *notebook,
                          GtkWidget   *child,
                          GtkWidget   *tab_label)
 {
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  
   gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1);
 }
 
+/**
+ * gtk_notebook_append_page_menu:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ *             or %NULL to use the default label, 'page N'.
+ * @menu_label: the widget to use as a label for the page-switch
+ *              menu, if that is enabled. If %NULL, and @tab_label
+ *              is a #GtkLabel or %NULL, then the menu label will be
+ *              a newly created label with the same text as @tab_label;
+ *              If @tab_label is not a #GtkLabel, @menu_label must be
+ *              specified if the page-switch menu is to be used.
+ * 
+ * Appends a page to @notebook, specifying the widget to use as the
+ * label in the popup menu.
+ **/
 void
 gtk_notebook_append_page_menu (GtkNotebook *notebook,
                               GtkWidget   *child,
                               GtkWidget   *tab_label,
                               GtkWidget   *menu_label)
 {
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
+  
   gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1);
 }
 
+/**
+ * gtk_notebook_prepend_page:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ *             or %NULL to use the default label, 'page N'.
+ *
+ * Prepends a page to @noteobook.
+ **/
 void
 gtk_notebook_prepend_page (GtkNotebook *notebook,
                           GtkWidget   *child,
                           GtkWidget   *tab_label)
 {
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  
   gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0);
 }
 
+/**
+ * gtk_notebook_prepend_page_menu:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ *             or %NULL to use the default label, 'page N'.
+ * @menu_label: the widget to use as a label for the page-switch
+ *              menu, if that is enabled. If %NULL, and @tab_label
+ *              is a #GtkLabel or %NULL, then the menu label will be
+ *              a newly created label with the same text as @tab_label;
+ *              If @tab_label is not a #GtkLabel, @menu_label must be
+ *              specified if the page-switch menu is to be used.
+ * 
+ * Prepends a page to @notebook, specifying the widget to use as the
+ * label in the popup menu.
+ **/
 void
 gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
                                GtkWidget   *child,
                                GtkWidget   *tab_label,
                                GtkWidget   *menu_label)
 {
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
+  
   gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0);
 }
 
+/**
+ * gtk_notebook_insert_page:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ *             or %NULL to use the default label, 'page N'.
+ * @position: the index (starting at 0) at which to insert the page,
+ *            or -1 to append the page after all other pages.
+ * 
+ * Insert a page into @notebook at the given position
+ **/
 void
 gtk_notebook_insert_page (GtkNotebook *notebook,
                          GtkWidget   *child,
                          GtkWidget   *tab_label,
                          gint         position)
 {
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  
   gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
 }
 
+/**
+ * gtk_notebook_insert_page_menu:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ *             or %NULL to use the default label, 'page N'.
+ * @menu_label: the widget to use as a label for the page-switch
+ *              menu, if that is enabled. If %NULL, and @tab_label
+ *              is a #GtkLabel or %NULL, then the menu label will be
+ *              a newly created label with the same text as @tab_label;
+ *              If @tab_label is not a #GtkLabel, @menu_label must be
+ *              specified if the page-switch menu is to be used.
+ * @position: the index (starting at 0) at which to insert the page,
+ *            or -1 to append the page after all other pages.
+ * 
+ * Insert a page into @notebook at the given position, specifying
+ * the widget to use as the label in the popup menu.
+ **/
 void
 gtk_notebook_insert_page_menu (GtkNotebook *notebook,
                               GtkWidget   *child,
@@ -3563,9 +3668,10 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
   GtkNotebookPage *page;
   gint nchildren;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (child != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+  g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
 
   page = g_new (GtkNotebookPage, 1);
   page->child = child;
@@ -3601,7 +3707,7 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
   else  
     {
       gtk_widget_ref (page->menu_label);
-      gtk_object_sink (GTK_OBJECT(page->menu_label));
+      gtk_object_sink (GTK_OBJECT (page->menu_label));
     }
 
   if (notebook->menu)
@@ -3659,6 +3765,16 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
     }
 }
 
+/**
+ * gtk_notebook_remove_page:
+ * @notebook: a #GtkNotebook.
+ * @page_num: the index of a notebook page, starting
+ *            from 0. If -1, the last page will
+ *            be removed.
+ * 
+ * Removes a page from the notebook given its index
+ * in the notebook.
+ **/
 void
 gtk_notebook_remove_page (GtkNotebook *notebook,
                          gint         page_num)
@@ -3689,10 +3805,19 @@ gtk_notebook_remove_page (GtkNotebook *notebook,
  * gtk_notebook_next_page
  * gtk_notebook_prev_page
  */
+/**
+ * gtk_notebook_get_current_page:
+ * @notebook: a #GtkNotebook
+ * 
+ * Returns the page number of the current page.
+ * 
+ * Return value: the index (starting from 0) of the current
+ * page in the notebook. If the notebook has no pages, then
+ * -1 will be returned.
+ **/
 gint
 gtk_notebook_get_current_page (GtkNotebook *notebook)
 {
-  g_return_val_if_fail (notebook != NULL, -1);
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
 
   if (!notebook->cur_page)
@@ -3701,13 +3826,22 @@ gtk_notebook_get_current_page (GtkNotebook *notebook)
   return g_list_index (notebook->children, notebook->cur_page);
 }
 
+/**
+ * gtk_notebook_get_nth_page:
+ * @notebook: a #GtkNotebook
+ * @page_num: the index of a page in the noteobok
+ * 
+ * Returns the child widget contained in page number @page_num.
+ * 
+ * Return value: the child widget, or %NULL if @page_num is
+ * out of bounds.
+ **/
 GtkWidget*
 gtk_notebook_get_nth_page (GtkNotebook *notebook,
                           gint         page_num)
 {
   GtkNotebookPage *page;
 
-  g_return_val_if_fail (notebook != NULL, NULL);
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
 
   page = g_list_nth_data (notebook->children, page_num);
@@ -3718,6 +3852,17 @@ gtk_notebook_get_nth_page (GtkNotebook *notebook,
   return NULL;
 }
 
+/**
+ * gtk_notebook_page_num:
+ * @notebook: a #GtkNotebook
+ * @child: a #GtkWidget
+ * 
+ * Finds the index of the page which contains the given child
+ * widget.
+ * 
+ * Return value: the index of the page containing @child, or
+ *   -1 if @child is not in the notebook.
+ **/
 gint
 gtk_notebook_page_num (GtkNotebook      *notebook,
                       GtkWidget        *child)
@@ -3725,16 +3870,14 @@ gtk_notebook_page_num (GtkNotebook      *notebook,
   GList *children;
   gint num;
 
-  g_return_val_if_fail (notebook != NULL, -1);
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
 
   num = 0;
   children = notebook->children;
   while (children)
     {
-      GtkNotebookPage *page;
-
-      page = children->data;
+      GtkNotebookPage *page =  children->data;
+      
       if (page->child == child)
        return num;
 
@@ -3745,32 +3888,46 @@ gtk_notebook_page_num (GtkNotebook      *notebook,
   return -1;
 }
 
+/**
+ * gtk_notebook_set_page:
+ * @notebook: a #GtkNotebook
+ * @page_num: index of the page to switch to, starting from 0.
+ *            If negative, or greater than the number of pages
+ *            in the notebook the last page will be used.
+ *                
+ * Switches to the page number @page_num.
+ **/
 void
 gtk_notebook_set_page (GtkNotebook *notebook,
                       gint         page_num)
 {
   GList *list;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   if (page_num >= 0)
     list = g_list_nth (notebook->children, page_num);
   else
-    {
-      list = g_list_last (notebook->children);
-      page_num = g_list_length (notebook->children) - 1;
-    }
+    list = g_list_last (notebook->children);
+
+  page_num = g_list_index (notebook->children, list);
+
   if (list)
     gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), page_num);
 }
 
+/**
+ * gtk_notebook_next_page:
+ * @notebook: a #GtkNotebook
+ * 
+ * Switches to the next page. Nothing happens if the current page is
+ * the last page.
+ **/
 void
 gtk_notebook_next_page (GtkNotebook *notebook)
 {
   GList *list;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   list = g_list_find (notebook->children, notebook->cur_page);
@@ -3784,12 +3941,18 @@ gtk_notebook_next_page (GtkNotebook *notebook)
   gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1);
 }
 
+/**
+ * gtk_notebook_prev_page:
+ * @notebook: a #GtkNotebook
+ * 
+ * Switches to the previous page. Nothing happens if the current page
+ * is the first page.
+ **/
 void
 gtk_notebook_prev_page (GtkNotebook *notebook)
 {
   GList *list;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   list = g_list_find (notebook->children, notebook->cur_page);
@@ -3814,6 +3977,15 @@ gtk_notebook_prev_page (GtkNotebook *notebook)
  * gtk_notebook_set_tab_vborder
  * gtk_notebook_set_scrollable
  */
+/**
+ * gtk_notebook_set_show_border:
+ * @notebook: a #GtkNotebook
+ * @show_border: %TRUE if a bevel should be drawn around the notebook.
+ * 
+ * Sets whether a bevel will be drawn around the notebook pages.
+ * this is only has an effect when the tabs are not shown.
+ * See gtk_notebook_set_show_tabs().
+ **/
 void
 gtk_notebook_set_show_border (GtkNotebook *notebook,
                              gboolean     show_border)
@@ -3830,6 +4002,13 @@ gtk_notebook_set_show_border (GtkNotebook *notebook,
     }
 }
 
+/**
+ * gtk_notebook_set_show_tabs:
+ * @notebook: a #GtkNotebook
+ * @show_tabs: %TRUE if the tabs should be shown.
+ * 
+ * Sets whether to show the tabs for the notebook or not.
+ **/
 void
 gtk_notebook_set_show_tabs (GtkNotebook *notebook,
                            gboolean     show_tabs)
@@ -3876,11 +4055,18 @@ gtk_notebook_set_show_tabs (GtkNotebook *notebook,
   gtk_widget_queue_resize (GTK_WIDGET (notebook));
 }
 
+/**
+ * gtk_notebook_set_tab_pos:
+ * @notebook: 
+ * @pos: 
+ * 
+ * Sets the edge at which the tabs for switching pages in the
+ * notebook are drawn.
+ **/
 void
 gtk_notebook_set_tab_pos (GtkNotebook     *notebook,
                          GtkPositionType  pos)
 {
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   if (notebook->tab_pos != pos)
@@ -3891,11 +4077,17 @@ gtk_notebook_set_tab_pos (GtkNotebook     *notebook,
     }
 }
 
+/**
+ * gtk_notebook_set_homogeneous_tabs:
+ * @notebook: a #GtkNotebook
+ * @homogeneous: %TRUE if all tabs should be the same size.
+ * 
+ * Sets whether the tabs must have all the same size or not.
+ **/
 void
 gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook,
                                   gboolean     homogeneous)
 {
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   if (homogeneous == notebook->homogeneous)
@@ -3905,11 +4097,21 @@ gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook,
   gtk_widget_queue_resize (GTK_WIDGET (notebook));
 }
 
+/**
+ * gtk_notebook_set_tab_border:
+ * @notebook: a #GtkNotebook
+ * @tab_border: %TRUE if there should be a border around the
+ *              tab labels.
+ * 
+ * Sets whether there should be a border around the tab labels
+ * in a notebook. This is equivalent to calling
+ * gtk_notebook_set_tab_hborder (@notebook, @tab_border) followed
+ * by gtk_noteobok_set_tab_vborder (@notebook, @tab_border).
+ **/
 void
 gtk_notebook_set_tab_border (GtkNotebook *notebook,
                             guint        tab_border)
 {
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   notebook->tab_hborder = tab_border;
@@ -3919,11 +4121,18 @@ gtk_notebook_set_tab_border (GtkNotebook *notebook,
     gtk_widget_queue_resize (GTK_WIDGET (notebook));
 }
 
+/**
+ * gtk_notebook_set_tab_hborder:
+ * @notebook: a #GtkNotebook
+ * @tab_vborder: %TRUE if the notebook tabs should have
+ *               a vertical border.
+ * 
+ * Sets whether the tabs should have a vertical border.
+ **/
 void
 gtk_notebook_set_tab_hborder (GtkNotebook *notebook,
                              guint        tab_hborder)
 {
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   if (notebook->tab_hborder == tab_hborder)
@@ -3935,11 +4144,18 @@ gtk_notebook_set_tab_hborder (GtkNotebook *notebook,
     gtk_widget_queue_resize (GTK_WIDGET (notebook));
 }
 
+/**
+ * gtk_notebook_set_tab_vborder:
+ * @notebook: a #GtkNotebook
+ * @tab_vborder: %TRUE if the notebook tabs should have
+ *               a vertical border.
+ * 
+ * Sets whether the tabs should have a vertical border.
+ **/
 void
 gtk_notebook_set_tab_vborder (GtkNotebook *notebook,
                              guint        tab_vborder)
 {
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   if (notebook->tab_vborder == tab_vborder)
@@ -3951,11 +4167,19 @@ gtk_notebook_set_tab_vborder (GtkNotebook *notebook,
     gtk_widget_queue_resize (GTK_WIDGET (notebook));
 }
 
+/**
+ * gtk_notebook_set_scrollable:
+ * @notebook: a #GtkNotebook
+ * @scrollable: %TRUE if scroll arrows should be added
+ * 
+ * Sets whether the tab label area will have arrows for scrolling if
+ * there are too many tabs to fit in the area.
+
+ **/
 void
 gtk_notebook_set_scrollable (GtkNotebook *notebook,
                             gboolean     scrollable)
 {
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   scrollable = (scrollable != FALSE);
@@ -3979,7 +4203,7 @@ gtk_notebook_set_scrollable (GtkNotebook *notebook,
        }
 
       if (GTK_WIDGET_VISIBLE (notebook))
-       gtk_widget_queue_resize (GTK_WIDGET(notebook));
+       gtk_widget_queue_resize (GTK_WIDGET (notebook));
     }
 }
 
@@ -3988,12 +4212,20 @@ gtk_notebook_set_scrollable (GtkNotebook *notebook,
  * gtk_notebook_popup_enable
  * gtk_notebook_popup_disable
  */
+
+
+/**
+ * gtk_notebook_popup_enable:
+ * @notebook: a #GtkNotebook
+ * 
+ * Enables the popup menu: if the user clicks with the right mouse button on
+ * the bookmarks, a menu with all the pages will be popped up.
+ **/
 void
 gtk_notebook_popup_enable (GtkNotebook *notebook)
 {
   GList *list;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   if (notebook->menu)
@@ -4011,10 +4243,15 @@ gtk_notebook_popup_enable (GtkNotebook *notebook)
                             gtk_notebook_menu_detacher);
 }
 
+/**
+ * gtk_notebook_popup_disable:
+ * @notebook: a #GtkNotebook
+ * 
+ * Disables the popup menu.
+ **/
 void       
 gtk_notebook_popup_disable  (GtkNotebook *notebook)
 {
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
   if (!notebook->menu)
@@ -4036,18 +4273,29 @@ gtk_notebook_popup_disable  (GtkNotebook *notebook)
  * gtk_notebook_set_tab_label_packing
  * gtk_notebook_query_tab_label_packing
  */
+
+/**
+ * gtk_notebook_get_tab_label:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * 
+ * Returns the tab label widget for the page @child. %NULL is returned
+ * if @child is not in @notebook or if no tab label has specifically
+ * been set for @child.
+ * 
+ * Return value: the tab label
+ **/
 GtkWidget *
 gtk_notebook_get_tab_label (GtkNotebook *notebook,
                            GtkWidget   *child)
 {
   GList *list;
 
-  g_return_val_if_fail (notebook != NULL, NULL);
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
   g_return_val_if_fail (child != NULL, NULL);
 
-  if (!(list = g_list_find_custom (notebook->children, child,
-                                  gtk_notebook_page_compare)))
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)  
     return NULL;
 
   if (GTK_NOTEBOOK_PAGE (list)->default_tab)
@@ -4056,6 +4304,16 @@ gtk_notebook_get_tab_label (GtkNotebook *notebook,
   return GTK_NOTEBOOK_PAGE (list)->tab_label;
 }  
 
+/**
+ * gtk_notebook_set_tab_label:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @tab_label: the tab label widget to use, or %NULL for default tab
+ *             label.
+ * 
+ * Changes the tab label for @child. If %NULL is specified
+ * for @tab_label, then the page will have the label 'page N'.
+ **/
 void
 gtk_notebook_set_tab_label (GtkNotebook *notebook,
                            GtkWidget   *child,
@@ -4064,18 +4322,16 @@ gtk_notebook_set_tab_label (GtkNotebook *notebook,
   GtkNotebookPage *page;
   GList *list;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
   g_return_if_fail (child != NULL);
-  
-  if (!(list = g_list_find_custom (notebook->children, child,
-                                  gtk_notebook_page_compare)))
-      return;
+
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)  
+    return;
 
   /* a NULL pointer indicates a default_tab setting, otherwise
    * we need to set the associated label
    */
-
   page = list->data;
   if (page->tab_label)
     gtk_widget_unparent (page->tab_label);
@@ -4109,6 +4365,15 @@ gtk_notebook_set_tab_label (GtkNotebook *notebook,
     }
 }
 
+/**
+ * gtk_notebook_set_tab_label_text:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @tab_label: the label text
+ * 
+ * Creates a new label and sets it as the tab label for the page
+ * containing @child.
+ **/
 void
 gtk_notebook_set_tab_label_text (GtkNotebook *notebook,
                                 GtkWidget   *child,
@@ -4116,24 +4381,36 @@ gtk_notebook_set_tab_label_text (GtkNotebook *notebook,
 {
   GtkWidget *tab_label = NULL;
 
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
   if (tab_text)
     tab_label = gtk_label_new (tab_text);
   gtk_notebook_set_tab_label (notebook, child, tab_label);
 }
 
+/**
+ * gtk_notebook_get_menu_label:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * 
+ * Returns the menu label of the page containing @child. NULL is
+ * returned if @child is not in @notebook or NULL if it has the
+ * default menu label.
+ * 
+ * Return value: the menu label
+ **/
 GtkWidget*
 gtk_notebook_get_menu_label (GtkNotebook *notebook,
                             GtkWidget   *child)
 {
   GList *list;
 
-  g_return_val_if_fail (notebook != NULL, NULL);
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
   g_return_val_if_fail (child != NULL, NULL);
 
-  if (!(list = g_list_find_custom (notebook->children, child,
-                                  gtk_notebook_page_compare)))
-      return NULL;
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)  
+    return NULL;
 
   if (GTK_NOTEBOOK_PAGE (list)->default_menu)
     return NULL;
@@ -4141,6 +4418,14 @@ gtk_notebook_get_menu_label (GtkNotebook *notebook,
   return GTK_NOTEBOOK_PAGE (list)->menu_label;
 }  
 
+/**
+ * gtk_notebook_set_menu_label:
+ * @notebook: a #GtkNotebook
+ * @child: the child widget
+ * @menu_label: the menu label, or NULL for default
+ * 
+ * Changes the menu label for the page containing @child. 
+ **/
 void
 gtk_notebook_set_menu_label (GtkNotebook *notebook,
                             GtkWidget   *child,
@@ -4153,19 +4438,17 @@ gtk_notebook_set_menu_label (GtkNotebook *notebook,
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
   g_return_if_fail (child != NULL);
 
-  if (!(list = g_list_find_custom (notebook->children, child,
-                                  gtk_notebook_page_compare)))
-      return;
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)  
+    return;
 
   page = list->data;
   if (page->menu_label)
     {
       if (notebook->menu)
-       {
-         gtk_container_remove (GTK_CONTAINER (notebook->menu), 
-                               page->menu_label->parent);
-         gtk_widget_queue_resize (notebook->menu);
-       }
+       gtk_container_remove (GTK_CONTAINER (notebook->menu), 
+                             page->menu_label->parent);
+
       if (!page->default_menu)
        gtk_widget_unref (page->menu_label);
     }
@@ -4184,6 +4467,14 @@ gtk_notebook_set_menu_label (GtkNotebook *notebook,
     gtk_notebook_menu_item_create (notebook, list);
 }
 
+/**
+ * gtk_notebook_set_menu_label_text:
+ * @notebook: a #GtkNotebook
+ * @child: the child widget
+ * @menu_text: the label text
+ * 
+ * Creates a new label and sets it as the menu label of @child.
+ **/
 void
 gtk_notebook_set_menu_label_text (GtkNotebook *notebook,
                                  GtkWidget   *child,
@@ -4191,11 +4482,44 @@ gtk_notebook_set_menu_label_text (GtkNotebook *notebook,
 {
   GtkWidget *menu_label = NULL;
 
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
   if (menu_text)
     menu_label = gtk_label_new (menu_text);
   gtk_notebook_set_menu_label (notebook, child, menu_label);
 }
 
+/* Helper function called when pages are reordered
+ */
+static void
+gtk_notebook_child_reordered (GtkNotebook     *notebook,
+                             GtkNotebookPage *page)
+{
+  if (notebook->menu)
+    {
+      GtkWidget *menu_item;
+      
+      menu_item = page->menu_label->parent;
+      gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label);
+      gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item);
+      gtk_notebook_menu_item_create (notebook, g_list_find (notebook->children, page));
+    }
+  
+  gtk_notebook_update_labels (notebook);
+}
+
+/**
+ * gtk_notebook_set_tab_label_packing:
+ * @notebook: a #GtkNotebook
+ * @child: the child widget
+ * @expand: whether to expand the bookmark or not
+ * @fill: whether the bookmark should fill the allocated area or not
+ * @pack_type: the position of the bookmark
+ * 
+ * Sets the packing parameters for the tab label of the page
+ * containing @child. See gtk_box_pack_start() for the exact meaning
+ * of the parameters.
+ **/
 void
 gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
                                    GtkWidget   *child,
@@ -4210,9 +4534,9 @@ gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
   g_return_if_fail (child != NULL);
 
-  if (!(list = g_list_find_custom (notebook->children, child,
-                                  gtk_notebook_page_compare)))
-      return;
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)  
+    return;
 
   page = list->data;
   if (page->pack == pack_type && page->expand == expand && page->fill == fill)
@@ -4224,26 +4548,26 @@ gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
   if (page->pack != pack_type)
     {
       page->pack = pack_type;
-      if (notebook->menu)
-       {
-         GtkWidget *menu_item;
-
-         menu_item = page->menu_label->parent;
-         gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label);
-         gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item);
-         gtk_notebook_menu_item_create (notebook, list);
-         gtk_widget_queue_resize (notebook->menu);
-       }
-      gtk_notebook_update_labels (notebook);
+      gtk_notebook_child_reordered (notebook, page);
     }
 
   if (!notebook->show_tabs)
     return;
 
-  gtk_notebook_pages_allocate (notebook, &(GTK_WIDGET (notebook)->allocation));
-  gtk_notebook_expose_tabs (notebook);
+  gtk_notebook_pages_allocate (notebook);
 }  
 
+/**
+ * gtk_notebook_query_tab_label_packing:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @expand: location to store the expand value (or NULL)
+ * @fill: location to store the fill value (or NULL)
+ * @pack_type: location to store the pack_type (or NULL)
+ * 
+ * Query the packing attributes for the tab label of the page
+ * containing @child.
+ **/
 void
 gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
                                      GtkWidget   *child,
@@ -4253,13 +4577,12 @@ gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
 {
   GList *list;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
   g_return_if_fail (child != NULL);
 
-  if (!(list = g_list_find_custom (notebook->children, child,
-                                  gtk_notebook_page_compare)))
-      return;
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)
+    return;
 
   if (expand)
     *expand = GTK_NOTEBOOK_PAGE (list)->expand;
@@ -4269,75 +4592,53 @@ gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
     *pack_type = GTK_NOTEBOOK_PAGE (list)->pack;
 }
 
+/**
+ * gtk_notebook_reorder_child:
+ * @notebook: a #GtkNotebook
+ * @child: the child to move
+ * @position: the new position
+ * 
+ * Reorders the page containing @child, so that it appears in position
+ * @position. Out of bounds @position will be clamped.
+ **/
 void
 gtk_notebook_reorder_child (GtkNotebook *notebook,
                            GtkWidget   *child,
                            gint         position)
 {
-  GList *list;
-  GList *work;
-  GtkNotebookPage *page = NULL;
+  GList *list, *new_list;
+  GtkNotebookPage *page;
   gint old_pos;
 
-  g_return_if_fail (notebook != NULL);
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-  g_return_if_fail (child != NULL);
   g_return_if_fail (GTK_IS_WIDGET (child));
 
-  for (old_pos = 0, list = notebook->children; list;
-       list = list->next, old_pos++)
-    {
-      page = list->data;
-      if (page->child == child)
-       break;
-    }
+  list = CHECK_FIND_CHILD (notebook, child);
+  if (!list)
+    return;
 
-  if (!list || old_pos == position)
+  old_pos = g_list_position (notebook->children, list);
+
+  if (old_pos == position)
     return;
 
-  notebook->children = g_list_remove_link (notebook->children, list);
-  
-  if (position <= 0 || !notebook->children)
-    {
-      list->next = notebook->children;
-      if (list->next)
-       list->next->prev = list;
-      notebook->children = list;
-    }
-  else if (position > 0 && (work = g_list_nth (notebook->children, position)))
-    {
-      list->prev = work->prev;
-      if (list->prev)
-       list->prev->next = list;
-      list->next = work;
-      work->prev = list;
-    }
-  else
-    {
-      work = g_list_last (notebook->children);
-      work->next = list;
-      list->prev = work;
-    }
+  page = list->data;
+  notebook->children = g_list_delete_link (notebook->children, list);
 
-  if (notebook->menu)
-    {
-      GtkWidget *menu_item;
+  position = CLAMP (position, 0, g_list_length (notebook->children));
 
-      g_assert(page != NULL);
+  notebook->children = g_list_insert (notebook->children, page, position);
+  new_list = g_list_nth (notebook->children, position);
 
-      menu_item = page->menu_label->parent;
-      gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label);
-      gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item);
-      gtk_notebook_menu_item_create (notebook, list);
-      gtk_widget_queue_resize (notebook->menu);
-    }
+  /* Fix up GList references in GtkNotebook structure */
+  if (notebook->first_tab == list)
+    notebook->first_tab = new_list;
+  if (notebook->focus_tab == list)
+    notebook->focus_tab = new_list;
 
-  gtk_notebook_update_labels (notebook);
+  /* Move around the menu items if necesary */
+  gtk_notebook_child_reordered (notebook, page);
 
   if (notebook->show_tabs)
-    {
-      gtk_notebook_pages_allocate (notebook,
-                                  &(GTK_WIDGET (notebook)->allocation));
-      gtk_notebook_expose_tabs (notebook);
-    }
+    gtk_notebook_pages_allocate (notebook);
 }
index ffa575c5085961b0f4b1bd9ba1ecd49a76ac38cc..8e110b678443d7368539d766fd95366a7edfddc9 100644 (file)
@@ -45,9 +45,6 @@ extern "C" {
 #define GTK_NOTEBOOK_GET_CLASS(obj)        (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_NOTEBOOK, GtkNotebookClass))
 
 
-#define GTK_NOTEBOOK_PAGE(_glist_)         ((GtkNotebookPage *)((GList *)(_glist_))->data)
-
-
 typedef struct _GtkNotebook       GtkNotebook;
 typedef struct _GtkNotebookClass  GtkNotebookClass;
 typedef struct _GtkNotebookPage   GtkNotebookPage;
@@ -58,7 +55,7 @@ struct _GtkNotebook
   
   GtkNotebookPage *cur_page;
   GList *children;
-  GList *first_tab;
+  GList *first_tab;            /* The first tab visible (for scrolling notebooks) */
   GList *focus_tab;
   
   GtkWidget *menu;
@@ -91,22 +88,6 @@ struct _GtkNotebookClass
                              guint            page_num);
 };
 
-struct _GtkNotebookPage
-{
-  GtkWidget *child;
-  GtkWidget *tab_label;
-  GtkWidget *menu_label;
-
-  guint default_menu : 1;
-  guint default_tab  : 1;
-  guint expand       : 1;
-  guint fill         : 1;
-  guint pack         : 1;
-
-  GtkRequisition requisition;
-  GtkAllocation allocation;
-};
-
 /***********************************************************
  *           Creation, insertion, deletion                 *
  ***********************************************************/
@@ -143,15 +124,15 @@ void gtk_notebook_remove_page       (GtkNotebook *notebook,
  *            query, set current NoteebookPage             *
  ***********************************************************/
 
-gint gtk_notebook_get_current_page   (GtkNotebook *notebook);
-GtkWidget* gtk_notebook_get_nth_page (GtkNotebook *notebook,
-                                     gint         page_num);
-gint gtk_notebook_page_num         (GtkNotebook *notebook,
-                                   GtkWidget   *child);
-void gtk_notebook_set_page         (GtkNotebook *notebook,
-                                   gint         page_num);
-void gtk_notebook_next_page        (GtkNotebook *notebook);
-void gtk_notebook_prev_page        (GtkNotebook *notebook);
+gint       gtk_notebook_get_current_page (GtkNotebook *notebook);
+GtkWidget* gtk_notebook_get_nth_page     (GtkNotebook *notebook,
+                                         gint         page_num);
+gint       gtk_notebook_page_num         (GtkNotebook *notebook,
+                                         GtkWidget   *child);
+void       gtk_notebook_set_page         (GtkNotebook *notebook,
+                                         gint         page_num);
+void       gtk_notebook_next_page        (GtkNotebook *notebook);
+void       gtk_notebook_prev_page        (GtkNotebook *notebook);
 
 /***********************************************************
  *            set Notebook, NotebookTab style              *
index 1262e94808ca55ab95749a71edc6c0fb06df00ce..01371b801d9dd982e5d0d7ccf930ed05e9ca045f 100644 (file)
@@ -1418,10 +1418,7 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
    * I wonder if focussable is a real word...
    */
   if (last_column == NULL)
-    {
-      gtk_container_set_focus_child (container, NULL);
-      return FALSE;
-    }
+    return FALSE;
 
   /* First thing we want to handle is entering and leaving the headers.
    */
@@ -1431,7 +1428,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
       if (!focus_child)
        {
          focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button;
-         gtk_container_set_focus_child (container, focus_child);
          gtk_widget_grab_focus (focus_child);
          goto cleanup;
        }
@@ -1446,7 +1442,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
       if (!focus_child)
        {
          focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
-         gtk_container_set_focus_child (container, focus_child);
          gtk_widget_grab_focus (focus_child);
          goto cleanup;
        }
@@ -1461,7 +1456,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
       if (!focus_child)
        {
          focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button;
-         gtk_container_set_focus_child (container, focus_child);
          gtk_widget_grab_focus (focus_child);
          goto cleanup;
        }
@@ -1476,7 +1470,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
       if (!focus_child)
        {
          focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
-         gtk_container_set_focus_child (container, focus_child);
          gtk_widget_grab_focus (focus_child);
          goto cleanup;
        }
@@ -1491,7 +1484,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
       if (!focus_child)
        {
          focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
-         gtk_container_set_focus_child (container, focus_child);
          gtk_widget_grab_focus (focus_child);
        }
       else
@@ -1504,7 +1496,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
       if (!focus_child)
        {
          focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
-         gtk_container_set_focus_child (container, focus_child);
          gtk_widget_grab_focus (focus_child);
        }
       else
@@ -1550,7 +1541,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
              GTK_WIDGET_CAN_FOCUS (column->button))
            {
              focus_child = column->button;
-             gtk_container_set_focus_child (container, column->button);
              gtk_widget_grab_focus (column->button);
              break;
            }
@@ -1578,10 +1568,6 @@ gtk_tree_view_header_focus (GtkTreeView        *tree_view,
                                      focus_child->allocation.x);
        }
     }
-  else
-    {
-      gtk_container_set_focus_child (container, NULL);
-    }
 
   return (focus_child != NULL);
 }
@@ -1619,16 +1605,11 @@ gtk_tree_view_focus (GtkContainer     *container,
        case GTK_DIR_TAB_BACKWARD:
          return (gtk_tree_view_header_focus (tree_view, direction));
        case GTK_DIR_UP:
-         gtk_container_set_focus_child (container, NULL);
          return FALSE;
        case GTK_DIR_TAB_FORWARD:
        case GTK_DIR_RIGHT:
        case GTK_DIR_DOWN:
-         if (direction == GTK_DIR_DOWN)
-           {
-             gtk_container_set_focus_child (container, NULL);
-           }
-         else
+         if (direction != GTK_DIR_DOWN)
            {
              if (gtk_tree_view_header_focus (tree_view, direction))
                return TRUE;
index 001b1c81929523d611b912c046770e125f2bcca4..315b256d40e59ccbce78828c0a29a4638ca19a91 100644 (file)
@@ -2856,6 +2856,32 @@ gtk_widget_real_grab_focus (GtkWidget *focus_widget)
     }
 }
 
+/**
+ * gtk_widget_is_focus:
+ * @widget: a #GtkWidget
+ * 
+ * Determines if the widget is the focus widget within its
+ * toplevel. (This does not mean that the HAS_FOCUS flag is
+ * necessarily set; HAS_FOCUS will only be set if the
+ * toplevel widget additionally has the global input focus.)
+ * 
+ * Return value: %TRUE if the widget is the focus widget.
+ **/
+gboolean
+gtk_widget_is_focus (GtkWidget *widget)
+{
+  GtkWidget *toplevel;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  toplevel = gtk_widget_get_toplevel (widget);
+  
+  if (GTK_IS_WINDOW (toplevel))
+    return widget == GTK_WINDOW (toplevel)->focus_widget;
+  else
+    return FALSE;
+}
+
 /**
  * gtk_widget_grab_default:
  * @widget: a #GtkWidget
index 0d86f3fe75e78ef974e74f1a51ff1ba88719ac05..70bfd6b964df25b23b079423ef89945d955c28c5 100644 (file)
@@ -493,6 +493,7 @@ gboolean   gtk_widget_intersect               (GtkWidget           *widget,
                                           GdkRectangle        *area,
                                           GdkRectangle        *intersection);
 
+gboolean   gtk_widget_is_focus            (GtkWidget           *widget);
 void      gtk_widget_grab_focus          (GtkWidget           *widget);
 void      gtk_widget_grab_default        (GtkWidget           *widget);
 
index 7860ef9379dd41dd3ff69c79bee163efe871776d..bea9bb646a5262d0fd3606666a7225626e50ab9e 100644 (file)
@@ -126,6 +126,8 @@ static gint gtk_window_focus_out_event    (GtkWidget         *widget,
 static gint gtk_window_client_event      (GtkWidget         *widget,
                                           GdkEventClient    *event);
 static void gtk_window_check_resize       (GtkContainer      *container);
+static gint gtk_window_focus              (GtkContainer     *container,
+                                          GtkDirectionType  direction);
 static void gtk_window_real_set_focus     (GtkWindow         *window,
                                           GtkWidget         *focus);
 
@@ -261,6 +263,7 @@ gtk_window_class_init (GtkWindowClass *klass)
   widget_class->expose_event = gtk_window_expose;
    
   container_class->check_resize = gtk_window_check_resize;
+  container_class->focus = gtk_window_focus;
 
   klass->set_focus = gtk_window_real_set_focus;
 }
@@ -1579,6 +1582,60 @@ gtk_window_check_resize (GtkContainer *container)
     gtk_window_move_resize (window);
 }
 
+static gboolean
+gtk_window_focus (GtkContainer     *container,
+                 GtkDirectionType  direction)
+{
+  GtkBin *bin = GTK_BIN (container);
+  GtkWindow *window = GTK_WINDOW (container);
+  GtkWidget *old_focus_child = container->focus_child;
+  GtkWidget *parent;
+  
+  /* We need a special implementation here to deal properly with wrapping
+   * around in the tab chain without the danger of going into an
+   * infinite loop.
+   */
+  if (old_focus_child)
+    {
+      if (GTK_IS_CONTAINER (old_focus_child) &&
+         GTK_WIDGET_DRAWABLE (old_focus_child) &&
+         GTK_WIDGET_IS_SENSITIVE (old_focus_child) &&
+         gtk_container_focus (GTK_CONTAINER (old_focus_child), direction))
+       return TRUE;
+    }
+
+  if (window->focus_widget)
+    {
+      /* Wrapped off the end, clear the focus setting for the toplpevel */
+      parent = window->focus_widget->parent;
+      while (parent)
+       {
+         gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
+         parent = GTK_WIDGET (parent)->parent;
+       }
+      
+      gtk_window_set_focus (GTK_WINDOW (container), NULL);
+    }
+
+  /* Now try to focus the first widget in the window */
+  if (GTK_WIDGET_DRAWABLE (bin->child) &&
+      GTK_WIDGET_IS_SENSITIVE (bin->child))
+    {
+      if (GTK_IS_CONTAINER (bin->child))
+       {
+         if (gtk_container_focus (GTK_CONTAINER (bin->child), direction))
+           return TRUE;
+       }
+      else if (GTK_WIDGET_CAN_FOCUS (bin->child))
+       {
+         gtk_widget_grab_focus (bin->child);
+         return TRUE;
+       }
+    }
+
+  return FALSE;
+}
+
 static void
 gtk_window_real_set_focus (GtkWindow *window,
                           GtkWidget *focus)
index 555ac978b18a3bcddf74cd4c1531fd1f3e4ea03f..e6420d3653bae800f0aba685f63536c53ef8a758 100644 (file)
@@ -6471,31 +6471,34 @@ GdkBitmap *book_closed_mask;
 GtkWidget *sample_notebook;
 
 static void
-page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+set_page_pixmaps (GtkNotebook *notebook, gint page_num,
+                 GdkPixmap *pixmap, GdkPixmap *mask)
 {
-  GtkNotebookPage *oldpage;
+  GtkWidget *page_widget;
   GtkWidget *pixwid;
 
-  oldpage = GTK_NOTEBOOK (widget)->cur_page;
+  page_widget = gtk_notebook_get_nth_page (notebook, page_num);
+
+  pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "tab_pixmap");
+  gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+  
+  pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "menu_pixmap");
+  gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+}
 
-  if (page == oldpage)
+static void
+page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+{
+  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+  gint old_page_num = gtk_notebook_get_current_page (notebook);
+  if (page_num == old_page_num)
     return;
-  pixwid = ((GtkBoxChild*)
-           (GTK_BOX (page->tab_label)->children->data))->widget;
-  gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
-  pixwid = ((GtkBoxChild*)
-           (GTK_BOX (page->menu_label)->children->data))->widget;
-  gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
-
-  if (oldpage)
-    {
-      pixwid = ((GtkBoxChild*)
-               (GTK_BOX (oldpage->tab_label)->children->data))->widget;
-      gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
-      pixwid = ((GtkBoxChild*)
-               (GTK_BOX (oldpage->menu_label)->children->data))->widget;
-      gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
-    }
+
+  set_page_pixmaps (notebook, page_num, book_open, book_open_mask);
+
+  if (old_page_num != -1)
+    set_page_pixmaps (notebook, old_page_num, book_closed, book_closed_mask);
 }
 
 static void
@@ -6589,19 +6592,25 @@ create_pages (GtkNotebook *notebook, gint start, gint end)
 
       label_box = gtk_hbox_new (FALSE, 0);
       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
+      gtk_object_set_data (GTK_OBJECT (child), "tab_pixmap", pixwid);
+                          
       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
       label = gtk_label_new (buffer);
       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
       gtk_widget_show_all (label_box);
 
+                                      
       menu_box = gtk_hbox_new (FALSE, 0);
       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
+      gtk_object_set_data (GTK_OBJECT (child), "menu_pixmap", pixwid);
+      
       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
       label = gtk_label_new (buffer);
       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
       gtk_widget_show_all (menu_box);
+
       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
     }
 }
@@ -6628,6 +6637,7 @@ standard_notebook (GtkButton   *button,
   gint i;
 
   gtk_notebook_set_show_tabs (notebook, TRUE);
+  gtk_notebook_set_show_border (notebook, TRUE);
   gtk_notebook_set_scrollable (notebook, FALSE);
   if (g_list_length (notebook->children) == 15)
     for (i = 0; i < 10; i++)
@@ -6641,6 +6651,20 @@ notabs_notebook (GtkButton   *button,
   gint i;
 
   gtk_notebook_set_show_tabs (notebook, FALSE);
+  gtk_notebook_set_show_border (notebook, TRUE);
+  if (g_list_length (notebook->children) == 15)
+    for (i = 0; i < 10; i++)
+      gtk_notebook_remove_page (notebook, 5);
+}
+
+static void
+borderless_notebook (GtkButton   *button,
+                    GtkNotebook *notebook)
+{
+  gint i;
+
+  gtk_notebook_set_show_tabs (notebook, FALSE);
+  gtk_notebook_set_show_border (notebook, FALSE);
   if (g_list_length (notebook->children) == 15)
     for (i = 0; i < 10; i++)
       gtk_notebook_remove_page (notebook, 5);
@@ -6651,6 +6675,7 @@ scrollable_notebook (GtkButton   *button,
                      GtkNotebook *notebook)
 {
   gtk_notebook_set_show_tabs (notebook, TRUE);
+  gtk_notebook_set_show_border (notebook, TRUE);
   gtk_notebook_set_scrollable (notebook, TRUE);
   if (g_list_length (notebook->children) == 5)
     create_pages (notebook, 6, 15);
@@ -6689,7 +6714,8 @@ create_notebook (void)
   {
     { "Standard",   standard_notebook },
     { "No tabs",    notabs_notebook },
-    { "Scrollable", scrollable_notebook }
+    { "Borderless", borderless_notebook },
+    { "Scrollable", scrollable_notebook },
   };
 
   if (!window)
@@ -6753,7 +6779,7 @@ create_notebook (void)
       label = gtk_label_new ("Notebook Style :");
       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
 
-      omenu = build_option_menu (items, 3, 0, sample_notebook);
+      omenu = build_option_menu (items, G_N_ELEMENTS (items), 0, sample_notebook);
       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
 
       button = gtk_button_new_with_label ("Show all Pages");
index 555ac978b18a3bcddf74cd4c1531fd1f3e4ea03f..e6420d3653bae800f0aba685f63536c53ef8a758 100644 (file)
@@ -6471,31 +6471,34 @@ GdkBitmap *book_closed_mask;
 GtkWidget *sample_notebook;
 
 static void
-page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+set_page_pixmaps (GtkNotebook *notebook, gint page_num,
+                 GdkPixmap *pixmap, GdkPixmap *mask)
 {
-  GtkNotebookPage *oldpage;
+  GtkWidget *page_widget;
   GtkWidget *pixwid;
 
-  oldpage = GTK_NOTEBOOK (widget)->cur_page;
+  page_widget = gtk_notebook_get_nth_page (notebook, page_num);
+
+  pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "tab_pixmap");
+  gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+  
+  pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "menu_pixmap");
+  gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+}
 
-  if (page == oldpage)
+static void
+page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+{
+  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+  gint old_page_num = gtk_notebook_get_current_page (notebook);
+  if (page_num == old_page_num)
     return;
-  pixwid = ((GtkBoxChild*)
-           (GTK_BOX (page->tab_label)->children->data))->widget;
-  gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
-  pixwid = ((GtkBoxChild*)
-           (GTK_BOX (page->menu_label)->children->data))->widget;
-  gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
-
-  if (oldpage)
-    {
-      pixwid = ((GtkBoxChild*)
-               (GTK_BOX (oldpage->tab_label)->children->data))->widget;
-      gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
-      pixwid = ((GtkBoxChild*)
-               (GTK_BOX (oldpage->menu_label)->children->data))->widget;
-      gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
-    }
+
+  set_page_pixmaps (notebook, page_num, book_open, book_open_mask);
+
+  if (old_page_num != -1)
+    set_page_pixmaps (notebook, old_page_num, book_closed, book_closed_mask);
 }
 
 static void
@@ -6589,19 +6592,25 @@ create_pages (GtkNotebook *notebook, gint start, gint end)
 
       label_box = gtk_hbox_new (FALSE, 0);
       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
+      gtk_object_set_data (GTK_OBJECT (child), "tab_pixmap", pixwid);
+                          
       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
       label = gtk_label_new (buffer);
       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
       gtk_widget_show_all (label_box);
 
+                                      
       menu_box = gtk_hbox_new (FALSE, 0);
       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
+      gtk_object_set_data (GTK_OBJECT (child), "menu_pixmap", pixwid);
+      
       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
       label = gtk_label_new (buffer);
       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
       gtk_widget_show_all (menu_box);
+
       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
     }
 }
@@ -6628,6 +6637,7 @@ standard_notebook (GtkButton   *button,
   gint i;
 
   gtk_notebook_set_show_tabs (notebook, TRUE);
+  gtk_notebook_set_show_border (notebook, TRUE);
   gtk_notebook_set_scrollable (notebook, FALSE);
   if (g_list_length (notebook->children) == 15)
     for (i = 0; i < 10; i++)
@@ -6641,6 +6651,20 @@ notabs_notebook (GtkButton   *button,
   gint i;
 
   gtk_notebook_set_show_tabs (notebook, FALSE);
+  gtk_notebook_set_show_border (notebook, TRUE);
+  if (g_list_length (notebook->children) == 15)
+    for (i = 0; i < 10; i++)
+      gtk_notebook_remove_page (notebook, 5);
+}
+
+static void
+borderless_notebook (GtkButton   *button,
+                    GtkNotebook *notebook)
+{
+  gint i;
+
+  gtk_notebook_set_show_tabs (notebook, FALSE);
+  gtk_notebook_set_show_border (notebook, FALSE);
   if (g_list_length (notebook->children) == 15)
     for (i = 0; i < 10; i++)
       gtk_notebook_remove_page (notebook, 5);
@@ -6651,6 +6675,7 @@ scrollable_notebook (GtkButton   *button,
                      GtkNotebook *notebook)
 {
   gtk_notebook_set_show_tabs (notebook, TRUE);
+  gtk_notebook_set_show_border (notebook, TRUE);
   gtk_notebook_set_scrollable (notebook, TRUE);
   if (g_list_length (notebook->children) == 5)
     create_pages (notebook, 6, 15);
@@ -6689,7 +6714,8 @@ create_notebook (void)
   {
     { "Standard",   standard_notebook },
     { "No tabs",    notabs_notebook },
-    { "Scrollable", scrollable_notebook }
+    { "Borderless", borderless_notebook },
+    { "Scrollable", scrollable_notebook },
   };
 
   if (!window)
@@ -6753,7 +6779,7 @@ create_notebook (void)
       label = gtk_label_new ("Notebook Style :");
       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
 
-      omenu = build_option_menu (items, 3, 0, sample_notebook);
+      omenu = build_option_menu (items, G_N_ELEMENTS (items), 0, sample_notebook);
       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
 
       button = gtk_button_new_with_label ("Show all Pages");